b7s / lara-ink
✒️ LaraInk - Turn your files into a standalone SPA with Alpine.js, powered by Laravel REST API + Bearer Token.
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/b7s/lara-ink
Requires
- php: >=8.3
- laravel/framework: >=11.0
Requires (Dev)
- pestphp/pest: ^4.0
This package is auto-updated.
Last update: 2025-11-20 19:59:35 UTC
README
LaraInk
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, 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
composer require b7s/lara-ink
Run the install command:
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 ink_make() ->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'], ];*/ ?> <div> <h1>{{ __('app.welcome_message', ['name' => auth()->user()->name]) }}</h1> @foreach($users as $user) <p> <a href="{{ ink_route('see-user', $user['id']) }}"> {{ $user['name'] }} </a> </p> @endforeach </div>
2. Build Your SPA
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:
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)
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):
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:
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:
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):
laraInkPlugin({ watchPaths: ['resources/lara-ink/**'], buildCommand: 'php artisan lara-ink:build', debounce: 1000 // milliseconds })
📖 Documentation
- Overview
- Getting Started
- Pages
- Components
- Layouts
- Alpine.js Integration
- Middleware
- Development Workflow
- Tailwind CSS
- Security Hardening
🎯 Example: Dynamic Page with API
<?php ink_make() ->title('User Profile') ->auth(true) ->cache(600); ?> <div x-data="profile()"> <h1>Profile: <span x-text="user.name"></span></h1> @foreach($posts as $post) <article> <h2>{{ $post->title }}</h2> <p>{{ $post->excerpt }}</p> </article> @endforeach <button @click="loadMore()">Load More</button> </div> <script> 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); } } } </script>
🔐 Example: Protected Page with Middleware
<?php ink_make() ->title('Admin Dashboard') ->middleware(['auth', 'verified', 'role:admin']) ->cache(false); ?> <div x-data="adminDashboard()"> <h1>Admin Dashboard</h1> <div class="stats-grid"> <div class="stat-card"> <h3>Total Users</h3> <p x-text="stats.users"></p> </div> <div class="stat-card"> <h3>Active Sessions</h3> <p x-text="stats.sessions"></p> </div> </div> </div> <script> function adminDashboard() { return { stats: {}, async init() { const response = await lara_ink.newReq('/api/admin/stats'); const data = await response.json(); this.stats = data; } } } </script>
🔧 Configuration
Edit config/lara-ink.php:
🧪 Testing
# 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 for more information.
🙏 Credits
- Author: Bruno Tenorio
- Email: b7s@outlook.com
- Built with ❤️ using Laravel and Alpine.js