rajtik76 / nette-tailwind
Nette: Standard Web Project with TailwindCSS
Requires
- php: >= 8.4
- latte/latte: ^3.1
- nette/application: ^3.2.3
- nette/assets: ^1.0.0
- nette/bootstrap: ^3.2.6
- nette/caching: ^3.2
- nette/database: ^3.2
- nette/di: ^3.2
- nette/forms: ^3.2
- nette/http: ^3.3
- nette/mail: ^4.0
- nette/robot-loader: ^4.0
- nette/security: ^3.2
- nette/utils: ^4.0
- rajtik76/nette-console: ^0.2
- tracy/tracy: ^2.10
Requires (Dev)
- nette/phpstan-rules: ^1.0
- nette/tester: ^2.5
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.1
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
A starter for PHP web applications built on Nette with Tailwind CSS 4. It is the official nette/web-project skeleton with Tailwind wired into its Vite build.
- PHP 8.4+, Nette 3.2, Latte 3
- Tailwind CSS 4 via
@tailwindcss/vite - Vite 8 with
@nette/vite-plugin, assets served bynette/assets nette-formsfor client-side form validation
Requirements
- PHP 8.4 or newer
- Composer
- Node.js 22.12+ and npm (
.nvmrcpins the version used in CI)
Installation
git clone https://github.com/rajtik76/nette-tailwind.git
cd nette-tailwind
composer install
npm install
npm run build
Make sure the temp/ and log/ directories are writable.
npm run build is required. Vite is enabled in config/common.neon, so the page
fails with "Failed to read Vite manifest" until the assets are built.
Development
Run the Vite dev server and a PHP server side by side:
npm run dev
php -S localhost:8000 -t www
Then open http://localhost:8000. In debug mode, {asset 'main.js'} loads assets
from the Vite dev server, so changes to templates and CSS show up immediately.
Without the dev server running, the last npm run build output is used.
Laravel Herd / Valet need a custom driver that serves www/ as the document root.
wwwDir is set explicitly in app/Bootstrap.php, because these servers boot
index.php through their own router script.
Console
php nette is the Nette counterpart of php artisan, provided by
rajtik76/nette-console:
php nette list # all commands
php nette make:command SendReport # app/Console/SendReportCommand.php, runs as app:send-report
php nette cache:clear # delete temp/cache
php nette package:discover # extensions registered by installed packages
Packages declare their DI extensions in composer.json (extra.nette.extensions) and
Bootstrap registers them automatically, so their commands work right after composer require.
Classes ending with Command in app/ are registered by search in services.neon.
The console runs in debug mode, so config changes apply without clearing the cache.
Set NETTE_DEBUG=0 in production.
Checks
composer run lint:check # Latte templates (own engine, warnings fail) + NEON config
composer run type:check # PHPStan level 8
composer run tester # Nette Tester smoke tests
composer run ci:check # all of the above, same as GitHub CI
Tests render the layout, so run npm run build first.
CI runs on PHP 8.4 and 8.5, Node version comes from .nvmrc.
How Tailwind is wired in
assets/main.cssimports Tailwind and adds@source "../app". Vite's root isassets/, so without it Tailwind would not scan the Latte templates inapp/.assets/main.jsis the Vite entry point and importsmain.css.vite.config.tsregisters thetailwindcss()plugin next to the Nette plugin.app/Presentation/@layout.latterenders{asset? 'main.js'}, which outputs both the<script>and the<link rel="stylesheet">for the bundled CSS.
Use Tailwind classes directly in any .latte file under app/.
Welcome and error pages
- Colors and the font are defined in
@themeinassets/main.css. The font (Instrument Sans) is loaded from Bunny Fonts by the welcome page only, through theheadblock of@layout.latte. Error pages make no external requests and fall back to the system font. - The cube illustrations are inline SVG blocks in
app/Presentation/@cubes.latte. Error4xx/@layout.lattewraps every 4xx template in a shared frame, so403.latte,404.latteetc. stay plain markup.500.phtmland503.phtmluse neither Tailwind nor the layout, because they must render even when the app or the asset build is broken. Their CSS is inline, so when you change colors inmain.css, update them there by hand.
Production
npm run build
Point the web server's document root to www/. Built assets go to www/assets/
(ignored by git, so build them on deploy).
Important: app/, config/, log/ and temp/ must never be web-accessible.
See the security warning.