Local Development
There are two supported local-development loops:
- Workbench development — the default loop for changing Lattice itself.
- External app source-linking — an integration loop for testing an unreleased checkout inside a real Laravel app with Vite HMR.
Use package-linking only when you want publish-like verification. It exercises the built dist package and therefore requires rebuilding after JavaScript changes.
Workbench development
Section titled “Workbench development”The repository ships with an Orchestra Testbench workbench app. This is the default way to develop Lattice because PHP, routes, fixtures, Vite, Tailwind, icons, and the React renderer are already wired together.
Install dependencies once:
composer installnpm installServe the workbench in two terminals — composer serve runs the PHP server (building the workbench app first), and npm run dev runs Vite for hot-reloading the React and CSS:
composer serve # PHP servernpm run dev # Vite HMR (separate terminal)The workbench compiles Lattice directly from resources/js and imports the stylesheet directly from resources/css/lattice.css, so frontend changes are picked up by Vite without running the package build.
The canonical references are:
workbench/resources/js/app.tsxworkbench/resources/css/app.cssvite.config.ts
External app source-linking
Section titled “External app source-linking”Use this when you need to try local Lattice changes inside an existing Laravel + Inertia React application. The PHP side is linked with Composer, and the React renderer is compiled from source by the consuming app’s Vite dev server.
This mode gives you HMR for Lattice’s TypeScript and CSS without running npm run build:lib.
Link PHP with Composer
Section titled “Link PHP with Composer”In the consuming app’s composer.json, add a path repository and require the dev version:
{ "repositories": [ { "type": "path", "url": "../lattice", "options": { "symlink": true } } ]}composer require lattice-php/lattice:"*@dev" -WComposer symlinks your checkout into vendor/lattice-php/lattice, so PHP changes are picked up by the app immediately.
Keep the public npm package installed
Section titled “Keep the public npm package installed”npm install @lattice-php/latticeKeep application imports on the public package name:
import LatticePage from "@lattice-php/lattice/page";import { Provider, registry } from "@lattice-php/lattice";Source-linking redirects that same public package name to your local checkout.
Configure Vite
Section titled “Configure Vite”Add the Lattice helper to the consuming app’s vite.config.ts:
import { lattice } from "@lattice-php/lattice/vite";import { defineConfig } from "vite";
const useLocalLattice = process.env.LATTICE_SOURCE === "1";
export default defineConfig({ plugins: [ lattice({ source: useLocalLattice, icons: { dirs: ["resources/icons"], }, }), // your existing Laravel, Inertia, React, and Tailwind plugins ],});This keeps normal development on the installed npm package, while LATTICE_SOURCE=1 switches Vite to the checkout under vendor/lattice-php/lattice. The helper configures the source aliases, Vite filesystem allow-list, React/Inertia dedupe, and the package-link Vitest dependency inline rule.
It also registers the SVG sprite plugin with Lattice’s built-in icons and any app icon dirs you pass through icons.dirs.
If your editor or tsc does not follow Vite aliases, mirror the public package name in tsconfig.json:
{ "compilerOptions": { "paths": { "@lattice-php/lattice": ["./vendor/lattice-php/lattice/resources/js/index.ts"], "@lattice-php/lattice/*": ["./vendor/lattice-php/lattice/resources/js/*"] } }}Scan Lattice source with Tailwind
Section titled “Scan Lattice source with Tailwind”Keep the regular stylesheet import, then add a Tailwind source path for the linked checkout:
@import "tailwindcss";@import "tw-animate-css";@import "@lattice-php/lattice/css";
@source "../../vendor/lattice-php/lattice/resources/js";Run the app in source mode
Section titled “Run the app in source mode”LATTICE_SOURCE=1 npm run devVite now compiles the linked checkout directly. TypeScript and CSS changes in Lattice update through the consuming app’s dev server without a package build.
Known issue: source-linked tests
Section titled “Known issue: source-linked tests”Source-linking is intended for browser development and HMR. It is not a reliable way to run the consuming app’s Vitest suite against a full Lattice checkout.
The checkout has its own node_modules, so React-based dependencies imported from Lattice source can resolve their own copy of React instead of the application’s copy. In tests this can show up as React’s “Invalid hook call” error. Browser dev and production builds dedupe correctly, but the test runner can still cross that dependency boundary.
For green test verification, switch back to package-linking or the published npm package so the app tests the built package surface rather than the checkout’s source tree.
Package-link verification
Section titled “Package-link verification”Use package-linking when you want to test the same surface that npm publishes:
npm install @lattice-php/lattice@file:../latticeThis mode reads the package exports and dist files. It is closer to a release, but it is not a live source workflow. Run the package build after renderer changes:
cd ../latticenpm run build:libFor a continuously refreshed package-link build:
cd ../latticenpm run build:lib:watchUse source-linking for daily integration work, and package-linking for publish-like checks.