lunx.docs
DocsQuick Start

Quick Start Guide

Bootstrap a new application from zero to running dev server in under 2 minutes. This guide walks through project setup, directory structure, and the full dev-to-production workflow.

1. Bootstrap with lunx create

The lunx create CLI generator provides zero-config templates for all 19 supported frameworks. It detects your Node version, installs dependencies, and writes a minimal config file automatically.

bash
# Interactive — picks framework, TypeScript, CSS for you
npm create lunx-dev@latest my-app

# Non-interactive for React + TypeScript + Tailwind
npm create lunx-dev@latest my-app -- --framework react --ts --tailwind

cd my-app && npm install
Minimal scaffolding
Lunx generates only what you need. A React + TypeScript project produces 6 files. No 200-file boilerplate. The lunx.config.ts is typically 3–5 lines.

2. Project structure

A fresh Lunx project is intentionally minimal. All framework-specific wiring is handled inside the adapter — not inside your project files.

textfile tree
my-app/
├── src/
   ├── main.tsx          # Application entry point
   ├── App.tsx           # Root component
   └── index.css         # Global styles / Tailwind input
├── index.html            # HTML entry template
├── lunx.config.ts       # Minimal Lunx configuration
├── tsconfig.json         # TypeScript config (auto-generated)
├── package.json
└── .gitignore

3. Understanding lunx.config.ts

The config uses defineConfig for full TypeScript autocomplete. Most fields have sensible defaults — you only declare what differs from the standard behavior.

typescriptlunx.config.ts
import { defineConfig } from 'lunx'

export default defineConfig({
  // Required: which framework adapter to use
  framework: 'react',

  // Optional overrides (all have sensible defaults)
  server: {
    port: 5173,         // default dev port
    host: true,         // expose to local network
    open: true,         // open browser on start
  },
  build: {
    outDir: 'dist',     // output directory
    minify: true,       // SWC + LightningCSS minification
    sourcemap: false,   // enable for debugging production
  },
  security: {
    scanSecrets: true,  // scan before every build
    checkCVEs: true,    // query OSV database for vulnerabilities
    generateSBOM: true, // CycloneDX 1.5 JSON/XML output
    sri: true,          // inject SHA-384 hashes into index.html
  },
})

4. Development workflow

01
Start the dev server

Powered by uWebSockets.js and rust-notify. Cold boot in ~36ms. File changes trigger HMR in ~18ms p99 — component state is preserved across module updates.

bash
npm run dev

 lunx v1.0.0  adapter: react  port: 5173
   Local:   http://localhost:5173
   Network: http://192.168.1.100:5173
    ready in 36ms
02
Make a change — HMR in action

Edit any source file. Lunx detects the change via rust-notify in ~6ms, recompiles only the changed module via SWC, and pushes the delta to your browser over WebSocket. No full page reload.

bash
# After editing src/App.tsx:
  [hmr] module updated: src/App.tsx (18ms)
  [hmr] 1 component reloaded  state preserved
03
Build for production

Lunx runs the 8-stage security pipeline before bundling. Any violation aborts the build. Output is minified, content-hashed, and SRI-protected.

bash
npm run build

🔍 Security scan...
   Secrets: 0 found across 84 files
   CVEs:    0 critical, 0 high in 312 packages
   SBOM:    dist/bom.json written (CycloneDX 1.5)
   SRI:     SHA-384 hashes injected into index.html

📦 dist/
  assets/main-cf861a.js     94.2 kB  gzip: 30.1 kB
  assets/style-d31e9a.css   12.4 kB  gzip:  3.6 kB
  index.html                 0.9 kB
   built in 512ms
04
Preview before deploy

Run a local preview of your production build to verify asset paths, service worker behavior, and confirm SRI hashes before pushing to production.

bash
npm run preview
   serving dist/  http://localhost:4173

5. Adding your first component

Lunx supports all standard React patterns — no special wrappers required. Create a component, import it, and HMR updates it instantly with state preserved.

typescriptsrc/components/Counter.tsx
import { useState } from 'react'

export function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div className="flex flex-col items-center gap-4 p-8">
      <h2 className="text-2xl font-bold tabular-nums">Count: {count}</h2>
      <div className="flex gap-3">
        <button
          onClick={() => setCount(c => c - 1)}
          className="px-4 py-2 rounded-lg border border-zinc-700 hover:bg-zinc-800"
        >
          Decrement
        </button>
        <button
          onClick={() => setCount(c => c + 1)}
          className="px-4 py-2 rounded-lg bg-blue-600 text-white hover:bg-blue-700"
        >
          Increment
        </button>
      </div>
    </div>
  )
}
Path aliases built-in
Lunx automatically resolves @/ as an alias to your src/ directory. Import using import { Counter } from '@/components/Counter' anywhere in your project.

6. Environment variables

Lunx uses .env files following the Vite convention. Only variables prefixed with LUNX_PUBLIC_ are exposed to the browser bundle — all others remain server-side only, preventing accidental secret leaks.

bash.env
# Browser-safe (exposed to client bundle)
LUNX_PUBLIC_API_URL=https://api.example.com
LUNX_PUBLIC_APP_NAME=My App

# Server-only (never exposed to client)
DATABASE_URL=postgres://user:pass@localhost/db
STRIPE_SECRET_KEY=sk_live_...
typescript
// Access in your components
const apiUrl = import.meta.env.LUNX_PUBLIC_API_URL