PrevelteKit Documentation
(Server Pre-Rendered)
Quick Start
Make sure you have node/npm installed. Here is a minimalistic example:mkdir -p preveltekit/src && cd preveltekit
echo '{"devDependencies": {"preveltekit": "^1.2.18"},"dependencies": {"svelte": "^5.39.11"},"scripts": {"dev": "preveltekit dev"}}' > package.json
npm install
echo '<script>let count = $state(0);</script><h1>Count: {count}</h1><button onclick={() => count++}>Click me</button>' > src/Index.svelte
npm run dev
# And open a browser with localhost:3000Core Features
⚡ Single Page Application with Built-time Pre-rendering (SPAwBR)
PrevelteKit combines the best of SPA and build-time rendering with hydration approaches. Unlike traditional SSR that renders on each request, or pure SPA that shows blank pages initially, SPAwBR pre-renders your layout and static content at build time while maintaining full interactivity through hydration. This provides fast initial page loads with visible content, then progressive enhancement as JavaScript loads.
🎯 Simple Architecture
Built on a clear separation between frontend and backend. Your frontend is purely static assets (HTML/CSS/JS) that can be served from any CDN or web server, while data comes from dedicated API endpoints. No JavaScript runtime required for serving.
⚡ Lightning Fast Builds
Built on Rsbuild for builds in the range of hundreds of milliseconds. The system automatically handles:
- TypeScript compilation and type checking
- Asset optimization and bundling
- CSS processing and minification
- Pre-compression (Brotli, Zstandard, Gzip)
🔧 Development Workflow
Three modes available to suit your needs:
- Development (npm run dev): Express server with fast rebuilds and live reloading
- Staging (npm run stage): Production build with local preview server
- Production (npm run build): Optimized build with pre-compression for deployment
Rendering Comparison
| Rendering Type | Initial Load | After Script |
|---|---|---|
| SSR (classic SSR / Next.js / Nuxt) | User sees content instantly (rendered on each request) | User sees content instantly (no additional loading) |
| SPA (React App / pure Svelte) | User sees white page or spinner (no content until JS loads) | User sees full content (after script execution) |
| SPA + Build-time Pre-Rendering (this approach) | User sees layout and static content (pre-rendered at build time) | User sees interactive content (hydrated with full functionality) |
SPAwBR Development
🔍 Detecting Build-time Pre-rendering
PrevelteKit uses window.__isBuildTime to indicate when code
is running during build-time pre-rendering. This is crucial for handling
client-side-only code like API calls and intervals.
// Basic detection
let renderInfo = "Client Rendered";
if (window?.__isBuildTime) {
renderInfo = "Server Pre-Rendered";
}🔄 Handling Client-Side Operations
PrevelteKit automatically handles fetch requests during build-time
pre-rendering. Fetch calls made during pre-rendering will timeout
after 5 seconds, allowing your components to render with loading
states. You no longer need to wrap fetch calls in window.__isBuildTime checks.
// Fetch automatically handled during pre-rendering
let pricePromise = $state(fetchBitcoinPrice());
// Use Svelte's await block for clean handling
{#await pricePromise}
<p>Loading...</p>
{:then data}
<p>{data}</p>
{:catch error}
<p>Error: {error.message}</p>
{/await}When to still use build-time checks:
- Browser APIs (localStorage, sessionStorage, geolocation)
- DOM manipulation that shouldn't happen during pre-rendering
- Third-party scripts that expect a real browser environment
Configuration
PrevelteKit uses rsbuild.config.ts for configuration
with sensible defaults. To customize settings, create an rsbuild.config.ts file in your project - it will merge with
the default configuration.
The framework provides fallback files (index.html and index.ts) from the default folder when you don't supply
your own. Once you add your own files, PrevelteKit uses those
instead, ignoring the defaults.
Client-Side Routing
PrevelteKit includes a built-in routing system that handles navigation between different pages in your application. The router uses pattern matching to determine which component to render based on the current URL path.
🧭 Route Configuration
Define your routes as an array of route objects, each specifying a path pattern, the component to render, and the static HTML file name:
const routes: Routes = {
dynamicRoutes: [
{
path: "*/doc",
component: Documentation
},
{
path: "*/example",
component: Example
},
{
path: "*/",
component: Landing
}
],
staticRoutes: [
{
path: "/doc",
htmlFilename: "doc.html"
},
{
path: "/example",
htmlFilename: "example.html"
},
{
path: "/",
htmlFilename: "index.html"
}
]
};
<Router routes>🔍 Path Patterns
PrevelteKit supports flexible path patterns for routing:
- Wildcard prefix (
*/path): Matches any single segment before the path (e.g.,*/docmatches/docand/any/doc) - Root wildcard (
*/): Matches the root path and single-segment paths - Exact paths (
/about): Matches the exact path only - Parameters (
/user/:id): Captures URL segments as parameters
🔗 Navigation
Use the route action for client-side navigation that updates
the URL without page reloads:
import { route } from 'preveltekit';
<a use:link href="doc">Documentation</a>
<a use:link href="example">Example</a>📄 Static File Mapping & Hybrid Routing
The staticRoutes array configuration serves a dual purpose
in PrevelteKit's hybrid routing approach:
htmlFilename: "doc.html" // Generates dist/doc.html at build timeStatic Generation: During the build process,
PrevelteKit generates actual HTML files in your dist/ folder
for each route:
dist/index.html- Pre-rendered root routedist/doc.html- Pre-rendered documentation pagedist/example.html- Pre-rendered example page
Dynamic Routing: Once the application loads, the same route configuration enables client-side navigation between pages without full page reloads. This provides:
- Fast initial page loads from pre-rendered static HTML
- Instant navigation between routes via client-side routing
- SEO benefits from static HTML while maintaining SPA functionality
This hybrid approach means users get static HTML files for direct access (bookmarks, search engines) and dynamic routing for seamless navigation within the application.
⚙️ Route Matching Priority
Routes are matched based on specificity, with more specific patterns taking precedence:
- Exact path matches (highest priority)
- Parameter-based routes
- Wildcard patterns (lowest priority)
Always place more specific routes before general wildcard routes in your configuration to ensure proper matching behavior.
Docker Support
Development environment:
docker build -f Dockerfile.dev . -t preveltekit-dev
docker run -p3000:3000 -v./src:/app/src preveltekit-devProduction build:
docker build . -t preveltekit
docker run -p3000:3000 preveltekitArchitecture Philosophy
PrevelteKit emphasizes static-first architecture with clear separation between frontend and backend:
- Frontend: Pure static assets (HTML/CSS/JS) served from any web server or CDN
- Backend: Dedicated API endpoints for data, can be built with any technology
- Deployment: No JavaScript runtime required - just static files
This approach offers compelling simplicity compared to full-stack meta-frameworks:
- Deploy anywhere (GitHub Pages, S3, any web server)
- Predictable performance with no server processes to monitor
- Easier debugging with clear boundaries
- Freedom to choose your backend technology
Deployment
The production build generates static files with pre-compressed variants:
- Standard files (.js, .css, .html)
- Brotli compressed (.br)
- Gzip compressed (.gz)
- Zstandard compressed (.zst)
Deploy to any static hosting or web server. The pre-compressed files enable optimal performance when served with appropriate web server configuration.
Why PrevelteKit?
While SvelteKit provides comprehensive capabilities, PrevelteKit focuses on a minimalistic solution for build-time pre-rendering. With less than 500 lines of code, it's essentially glue code for Svelte, Rsbuild, and jsdom - perfect for projects that need fast initial loads without the complexity of full JavaScript infrastructure for the frontend deployment.
PrevelteKit serves as a starting point for projects that need pre-rendered content without the overhead of a full meta-framework, following a "convention over configuration" approach.