b7s/lara-ink

✒️ LaraInk - Turn your files into a standalone SPA with Alpine.js, powered by Laravel REST API + Bearer Token.

Maintainers

Details

github.com/b7s/lara-ink

Source

Issues

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/b7s/lara-ink

v0.1.2 2025-11-05 15:17 UTC

This package is auto-updated.

Last update: 2025-11-20 19:59:35 UTC


README

[LaraInk]

LaraInk

PHP Version Laravel Version 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, 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

🎯 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

🔗 Links