Repository navigation
Tech Stack
Karthik P edited this page Oct 16, 2026
·
8 revisions
Blinkql is a static, client-only single-page application. Everything below runs in the user's browser; the only infrastructure is static hosting.
flowchart LR
UI["React + TypeScript UI<br/>shadcn/ui · Tailwind"] -->|SQL| W["DuckDB-wasm<br/>(Web Worker)"]
W -->|Arrow record batches| UI
W <--> S[("OPFS / IndexedDB")]
W <-->|HTTP range requests| R["Remote Parquet / CSV"]
| Layer | Choice | Why |
|---|---|---|
| Language |
TypeScript (strict mode, noUncheckedIndexedAccess) |
Type safety across the UI and the engine boundary |
| UI framework | React | Mature ecosystem, widely known by contributors. Keeping React fast with large data is part of the engineering challenge; see ADR-002 |
| Build tool & dev server | Vite | Fast builds, first-class Web Worker and WebAssembly handling, static output |
| Query engine |
DuckDB-wasm (@duckdb/duckdb-wasm) |
Columnar analytical SQL in the browser; native CSV, Parquet and JSON readers; reads remote files with HTTP range requests |
| In-memory data format |
Apache Arrow JS (apache-arrow) |
Columnar results that cross the worker boundary without row-by-row conversion |
| Threading | Web Workers: DuckDB-wasm's worker-based async API, plus Comlink for any additional Blinkql workers | Query execution and heavy processing stay off the main thread |
| SQL editor |
CodeMirror 6 with @codemirror/lang-sql
|
Lightweight and modular, with schema-aware autocomplete; see ADR-005 |
| Results grid | TanStack Virtual, evolving to a custom canvas-rendered grid | Only visible rows are rendered; the canvas grid is a planned performance milestone |
| Charts | Apache ECharts (canvas renderer), plus uPlot for dense time series | Canvas rendering scales to large point counts where SVG struggles |
| UI components | shadcn/ui (Base UI primitives, Mira style) + Tailwind CSS v4 | Accessible primitives and a consistent design, with components owned in the repo. Base UI has been shadcn/ui's default since July 2026 and is its recommendation for new projects; see ADR-009 and Design Language |
| Icons | lucide-react | Consistent, tree-shakeable icon set |
| Typography | Atkinson Hyperlegible Next and Mono, self-hosted via Fontsource | Built to tell similar characters apart (0/O, 1/l/I) in codes and IDs; no runtime font CDN. See Design Language |
| UI state | Zustand | Minimal, selector-based subscriptions. Large result data is deliberately kept outside React state; see ADR-004 |
| Local persistence | OPFS for data files, IndexedDB for saved queries, history and settings | Fast, origin-private storage that survives reloads |
| Offline (planned) |
Service worker via vite-plugin-pwa
|
Caches the app shell and engine for instant repeat loads and offline use |
| Purpose | Tool |
|---|---|
| Package manager | pnpm |
| Linting & formatting | Biome, one tool for both, including the React hooks rules; see ADR-010 |
| Unit & integration tests | Vitest + React Testing Library |
| End-to-end tests | Playwright (Chromium, Firefox, WebKit) |
| Accessibility checks |
axe-core via @axe-core/playwright
|
| Benchmarks | Custom Playwright-driven harness using the User Timing API (performance.mark / measure), plus tinybench for micro-benchmarks |
| Performance audits | Lighthouse CI, React Profiler, Chrome DevTools performance traces |
| Bundle budgets |
size-limit, with rollup-plugin-visualizer for analysis |
| Commit conventions |
Conventional Commits, enforced with commitlint: locally through a Lefthook commit-msg hook, and on PR titles in CI |
| Releases & changelog | release-please |
| Dependency updates | Dependabot |
| Stage | Setup |
|---|---|
| Continuous integration | GitHub Actions: typecheck, lint, unit tests, build, end-to-end tests, bundle-size check and a benchmark smoke test on every pull request |
| Preview environments | A Vercel preview deployment for every pull request |
| Production |
Vercel static hosting at blinkql.vercel.app, deployed from main
|
| Engine assets | DuckDB-wasm bundles and the DuckDB extensions Blinkql uses (parquet, json) are self-hosted (same origin, version-pinned, long-term cached; extensions are checksum-verified at build time) rather than loaded from a CDN; see ADR-008
|
Response headers are set in vercel.json, the single source for production, previews and local development (Vite's dev and preview servers read the same file):
| Header | Value | Why |
|---|---|---|
Cross-Origin-Opener-Policy |
same-origin |
With COEP, makes the page cross-origin isolated: required for SharedArrayBuffer, multithreading and precise memory measurement |
Cross-Origin-Embedder-Policy |
require-corp |
credentialless would be more lenient, but Safari doesn't support it |
Cross-Origin-Resource-Policy |
same-origin |
Other sites can't embed Blinkql's files |
Content-Security-Policy |
Scripts, styles, fonts, workers and connections from Blinkql's own origin only, plus 'wasm-unsafe-eval' for WebAssembly; no plugins; can't be framed |
See Privacy & Security. Loosen it deliberately, in the PR that needs it (for example connect-src for remote queries) |
X-Content-Type-Options |
nosniff |
Browsers never guess a file's type |
Referrer-Policy |
strict-origin-when-cross-origin |
Remote hosts see only the origin, never the full URL |
Permissions-Policy |
Camera, microphone, location, payment, USB and Topics disabled | Blinkql uses none of them |
Cache-Control on /assets/*
|
public, max-age=31536000, immutable |
Vite puts a content hash in these filenames, so they never change |
The CSP is left out of pnpm dev only, because Vite's hot reload needs inline scripts. End-to-end tests run against the production build with every header, and each deploy fails if a header is missing (scripts/verify-headers.ts).
- No server framework (Next.js, a Node API, etc.). There's nothing to render or serve dynamically; see ADR-001 and ADR-002.
- No Redux. UI state is small, and large data doesn't live in a store.
- No Monaco Editor. It adds several megabytes and hurts cold-start time.
- No SVG charting for large series. SVG creates one DOM node per point and doesn't scale.
⚡ Blinkql: queries in the blink of an eye · MIT licensed · Live app · Issues · Discussions
Project
Engineering
- Tech Stack
- Architecture
- Performance & Benchmarks
- Decision Records (ADRs)
- Privacy & Security
- Browser Support & Limitations
Design
Community