A template for building offline-first Progressive Web Apps with SvelteKit, SQLite (via OPFS), and push notifications.
- SQLite with OPFS - Persistent client-side database using Origin Private File System
- PWA Ready - Service worker, manifest, and installable on all platforms
- Push Notifications - Works on desktop and mobile (including iOS when installed)
- Svelte 5 - Latest runes-based reactivity
- TypeScript - Full type safety
- Tailwind CSS v4 - Utility-first styling
- Vitest - Unit and component testing
# Clone the template
git clone https://github.com/YOUR_USERNAME/svelte-sqlite-pwa.git my-app
cd my-app
# Install dependencies
bun install
# Start development server
bun run devOpen http://localhost:5173 in your browser.
# Start dev server
bun run dev
# Run tests
bun run test
# Type check
bun run check
# Lint and format
bun run lint
bun run format# Build the app
bun run build
# Preview production build
bun run previewsrc/
├── lib/
│ ├── db/ # SQLite database layer
│ │ ├── sqlite.ts # Main DB API
│ │ ├── sqlite-worker.ts # Web Worker for SQLite
│ │ └── index.ts # Exports
│ └── notifications/ # Push notification utilities
├── routes/
│ └── +page.svelte # Demo page
└── app.d.ts # TypeScript declarations
import { db } from '$lib/db';
// Initialize (call once on app start)
await db.init();
// Execute statements
await db.exec(`
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
)
`);
// Insert/Update/Delete
const result = await db.run(
'INSERT INTO users (name) VALUES (?)',
['Alice']
);
console.log(result.lastInsertRowid);
// Query multiple rows
const users = await db.query<{ id: number; name: string }>(
'SELECT * FROM users WHERE name LIKE ?',
['%ali%']
);
// Query single row
const user = await db.queryOne<{ id: number; name: string }>(
'SELECT * FROM users WHERE id = ?',
[1]
);The database automatically uses OPFS (Origin Private File System) when available, providing persistent storage that survives page refreshes and browser restarts. Falls back to in-memory storage on unsupported browsers.
Requirements for OPFS:
- Modern browser with OPFS support
- Served over HTTPS (or localhost)
- COOP/COEP headers (configured in
vite.config.ts)
import { notifications } from '$lib/notifications';
// Initialize (checks platform capabilities)
notifications.init();
// Check status
if (notifications.canRequest) {
await notifications.requestPermission();
}
// Send test notification
if (notifications.isGranted) {
await notifications.sendTest();
}iOS Note: Push notifications on iOS require the app to be installed to the home screen (Add to Home Screen from Safari).
The template includes:
- COOP/COEP headers for SharedArrayBuffer (required by SQLite OPFS)
- Worker configuration for ES modules
- PWA plugin with workbox caching
Edit the manifest in vite.config.ts to customize:
- App name and description
- Theme colors
- Icons
| Platform | SQLite OPFS | Push Notifications |
|---|---|---|
| Chrome/Edge 102+ | Full | Full |
| Firefox 111+ | Full | Full |
| Safari 15.2+ | Full | Full |
| iOS Safari 17+ | Full | Home screen only |
| iOS Safari 16.4+ | Limited | Home screen only |
MIT