https://github.com/b7s/lara-ink
✒️ LaraInk - Turn your Blade files into a standalone reactive SPA with Alpine.js, powered by Laravel REST API + Bearer Token.
https://github.com/b7s/lara-ink
Last synced: 5 months ago
JSON representation
✒️ LaraInk - Turn your Blade files into a standalone reactive SPA with Alpine.js, powered by Laravel REST API + Bearer Token.
- Host: GitHub
- URL: https://github.com/b7s/lara-ink
- Owner: b7s
- Created: 2025-11-01T05:12:49.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-11-20T19:59:33.000Z (7 months ago)
- Last Synced: 2025-11-20T21:19:25.978Z (7 months ago)
- Language: PHP
- Homepage:
- Size: 354 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Security: docs/security-hardening.md
Awesome Lists containing this project
README
LaraInk
[](https://php.net)
[](https://laravel.com)
[](LICENSE)
---
**Laravel Blade + Alpine.js = static to reactive SPAs in seconds.**
A powerful DSL compiler that transforms Blade-like files into an independent SPA with [Alpine.js](https://alpinejs.dev), communicating with Laravel via REST API using Bearer Token authentication
---
## ✨ Features
- 🚀 **Blade-to-Alpine.js Compiler** - Write familiar Blade syntax, get reactive Alpine.js components
- 📦 **Independent SPA** - Deploy your frontend anywhere (CDN, Netlify, Vercel, S3)
- 🔐 **Bearer Token Auth** - Secure API communication with Laravel Sanctum
- ⚡ **Smart Caching** - Page-level caching with configurable TTL
- 🎯 **Dynamic Routing** - File-based routing with parameter support
- 🌍 **i18n Ready** - Built-in translation system
- 🎨 **Layout System** - Reusable layouts with nested folder support
- 📱 **SPA Router** - Client-side navigation with prefetching
- 🔧 **PHP Variables** - Define variables in PHP blocks, auto-converted to Alpine.js reactive data
- 🛡️ **Type Safety** - Automatic type detection and validation for variables (string, int, float, bool, array, Collection, Eloquent)
- 🧪 **With a lot of tests**
---
## 📦 Installation
```bash
composer require b7s/lara-ink
```
Run the install command:
```bash
php artisan lara-ink:install
```
The package will automatically:
- Create required directories (`resources/lara-ink/`, `public/build/`, etc.)
- Publish configuration file to `config/lara-ink.php`
- Set up default layout
- Set up Vite plugin to project root
---
## 🚀 Quick Start
### 1. Create Your First Page
Create `resources/lara-ink/pages/index.php`:
```php
title(__('app.welcome'))
->layout('app')
->auth(true)
->middleware(['auth', 'role:admin'])
->cache(now()->addMinutes(10));
$users = User::all()->toArray();
/*
// It returns something like this:
[
['id' => 1, 'name' => 'John Doe'],
['id' => 2, 'name' => 'Max Mustermann'],
];*/
?>
{{ __('app.welcome_message', ['name' => auth()->user()->name]) }}
@foreach($users as $user)
@endforeach
```
### 2. Build Your SPA
```bash
php artisan lara-ink:build
```
### 3. Access Your App
Open `http://your-app.test/` in your browser!
If you are running inside Laravel, create a route to serve the index page:
```php
Route::get('/{path?}', function () {
require ink_path('index.html');
})->where('path', '.*');
```
---
## 🔥 Hot Reload Development
LaraInk offers two ways to enable hot reload during development:
### Option 1: Native Dev Command (for quick start)
```bash
php artisan lara-ink:dev
```
This will:
- ✅ Watch for changes in `resources/lara-ink/**`
- ✅ Auto-rebuild when files change
- ✅ Show build status in terminal
- ✅ No Node.js required
### Option 2: Vite Integration (Recommended - Full Browser Hot Reload)
For automatic browser refresh, integrate with Vite:
**1. Install Vite (if not already installed):**
```bash
npm install -D vite laravel-vite-plugin
```
**2. The Vite plugin is automatically copied to your project root during `composer install`. Just import it in `vite.config.js`:**
```javascript
import { defineConfig } from 'vite';
// Add this lines if not already added
import laravel from 'laravel-vite-plugin';
import laraInkPlugin from './vite-plugin-lara-ink.js';
export default defineConfig({
plugins: [
// Add laravel plugin if not already added
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
// Add LaraInk Hot Reload - No configuration needed!
laraInkPlugin(),
],
});
```
**3. Start Vite dev server:**
```bash
npm run dev
```
The plugin will:
- ✅ Build all pages on startup (if not already built)
- ✅ Watch for changes in `resources/lara-ink/`
- ✅ Rebuild only affected pages when you save
- ✅ Automatically reload your browser
**Smart Compilation:**
- **Page changed** → Rebuilds only that page
- **Layout changed** → Rebuilds all pages using that layout
- **Component changed** → Rebuilds all pages using that component
**Custom Configuration (Optional):**
```javascript
laraInkPlugin({
watchPaths: ['resources/lara-ink/**'],
buildCommand: 'php artisan lara-ink:build',
debounce: 1000 // milliseconds
})
```
---
## 📖 Documentation
- [Overview](docs/README.md)
- [Getting Started](docs/getting-started.md)
- [Pages](docs/pages.md)
- [Components](docs/components.md)
- [Layouts](docs/layouts.md)
- [Alpine.js Integration](docs/alpine.md)
- [Middleware](docs/middleware.md)
- [Development Workflow](docs/development.md)
- [Tailwind CSS](docs/tailwind-css.md)
- [Security Hardening](docs/security-hardening.md)
---
## 🎯 Example: Dynamic Page with API
```php
title('User Profile')
->auth(true)
->cache(600);
?>
Profile:
@foreach($posts as $post)
{{ $post->title }}
{{ $post->excerpt }}
@endforeach
Load More
function profile() {
return {
user: {},
posts: [],
async init() {
const response = await lara_ink.newReq('/api/profile');
const data = await response.json();
this.user = data.user;
this.posts = data.posts;
},
async loadMore() {
const response = await lara_ink.newReq('/api/posts?page=2');
const data = await response.json();
this.posts.push(...data.posts);
}
}
}
```
### 🔐 Example: Protected Page with Middleware
```php
title('Admin Dashboard')
->middleware(['auth', 'verified', 'role:admin'])
->cache(false);
?>
Admin Dashboard
Total Users
Active Sessions
function adminDashboard() {
return {
stats: {},
async init() {
const response = await lara_ink.newReq('/api/admin/stats');
const data = await response.json();
this.stats = data;
}
}
}
```
---
## 🔧 Configuration
Edit `config/lara-ink.php`:
---
## 🧪 Testing
```bash
# Run all tests
composer test
# Run specific test group
./vendor/bin/pest --group=unit
```
---
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
---
## 📄 License
The MIT License (MIT). Please see [License File](LICENSE) for more information.
---
## 🙏 Credits
- **Author**: Bruno Tenorio
- **Email**: b7s@outlook.com
- Built with ❤️ using [Laravel](https://laravel.com) and [Alpine.js](https://alpinejs.dev)
---
## 🔗 Links
- [Documentation](docs/)
- [Issues](https://github.com/b7s/lara-ink/issues)
- [Changelog](CHANGELOG.md)