{"id":50794389,"url":"https://github.com/korbinjoe/vontjs","last_synced_at":"2026-06-12T13:32:02.820Z","repository":{"id":325678615,"uuid":"1102031078","full_name":"korbinjoe/vontjs","owner":"korbinjoe","description":"A lightweight and high-performance full-stack TypeScript framework combining Koa and React/Vue with file-based routing and hot module replacement","archived":false,"fork":false,"pushed_at":"2025-12-19T14:28:58.000Z","size":27303,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-24T10:42:01.727Z","etag":null,"topics":["framework","full-stack","fullstack","generator","koa","lightweight","nodejs","react","scaffolding","vue","web-development"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/korbinjoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-22T17:32:57.000Z","updated_at":"2025-12-19T14:29:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/korbinjoe/vontjs","commit_stats":null,"previous_names":["korbinzhao/vontjs","korbinjoe/vontjs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/korbinjoe/vontjs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korbinjoe%2Fvontjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korbinjoe%2Fvontjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korbinjoe%2Fvontjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korbinjoe%2Fvontjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/korbinjoe","download_url":"https://codeload.github.com/korbinjoe/vontjs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/korbinjoe%2Fvontjs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34247461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["framework","full-stack","fullstack","generator","koa","lightweight","nodejs","react","scaffolding","vue","web-development"],"created_at":"2026-06-12T13:31:57.704Z","updated_at":"2026-06-12T13:31:58.906Z","avatar_url":"https://github.com/korbinjoe.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# vont\n\n\u003e 🚀 A lightweight full-stack TypeScript framework combining Koa and React/Vue with file-based routing and hot module replacement\n\n[![npm version](https://img.shields.io/npm/v/vont.svg)](https://www.npmjs.com/package/vont)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.1-blue.svg)](https://www.typescriptlang.org/)\n\n## ✨ Features\n\n- 📁 **File-based Routing** - Automatic API and page routes based on file structure\n- 🔥 **Hot Module Replacement** - Instant feedback during development\n- ⚙️ **Zero Configuration** - Convention over configuration\n- 🔤 **TypeScript First** - Full type safety across your entire stack\n- 📡 **REST API Routes** - Simple function exports become API endpoints\n- ⚛️ **React \u0026 Vue Support** - Choose your preferred frontend framework\n- 🎯 **Type Safety** - Share types between frontend and backend\n- 🏗️ **Production Ready** - Single unified deployment\n- 🔒 **Clean Architecture** - Internal files hidden in `.vont/` directory\n- ⚡ **Vite 7 Powered** - Lightning-fast builds and HMR\n\n## 🚀 Quick Start\n\n### Create a New Project\n\nVont provides an interactive CLI to scaffold new projects with ease:\n\n#### Interactive Mode (Recommended)\n\n```bash\n# Using npx (no installation needed)\nnpx vont create\n\n# Or install globally first\nnpm install -g vont\nvont create\n```\n\n**Interactive Setup:**\n\n```\n? Project name: › my-awesome-app\n? Select a framework: › - Use arrow-keys. Return to submit.\n❯ React\n  Vue\n```\n\n1. **Enter project name** - Type your project name (validated for valid characters)\n2. **Select framework** - Use ↑↓ arrow keys to choose, press Enter to confirm\n3. **Done!** - Vont creates your project with all necessary files\n\n#### Non-Interactive Mode\n\nFor automation or when you know what you want:\n\n```bash\n# With project name (will prompt for framework)\nvont create my-app\n\n# Fully non-interactive (CI/CD friendly)\nvont create my-app --template react-ts\nvont create my-app --template vue-ts\n\n# Flexible argument order\nvont create --template react-ts my-app\n```\n\n**Supported Formats:**\n- `--template=react-ts` (equals sign)\n- `--template react-ts` (space separated)\n\n#### Next Steps\n\n```bash\ncd my-app\nnpm install\nnpm run dev\n```\n\nVisit `http://localhost:3000` 🎉\n\n**What You Get:**\n- ✅ Complete project structure\n- ✅ TypeScript configuration\n- ✅ Vite development server\n- ✅ Hot Module Replacement\n- ✅ Example pages and API routes\n- ✅ Type-safe API client\n\n### Add to Existing Project\n\n```bash\nnpm install vont --save-dev\n```\n\nUpdate your `package.json`:\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"vont dev\",\n    \"build\": \"vont build\",\n    \"start\": \"vont start\"\n  }\n}\n```\n\n## 📖 Documentation\n\n### Table of Contents\n\n- [Project Structure](#project-structure)\n- [API Routes](#api-routes)\n- [Page Routes](#page-routes)\n- [Configuration](#configuration)\n- [CLI Commands](#cli-commands)\n- [Deployment](#deployment)\n- [Examples](#examples)\n\n## 📁 Project Structure\n\n## 📁 Project Structure\n\n### 1. Update your `package.json`\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"vont dev\",\n    \"build\": \"vont build\",\n    \"start\": \"vont start\"\n  }\n}\n```\n\n### 2. File Structure\n\n```\nyour-project/\n├── src/\n│   ├── api/              # Backend API routes\n│   │   ├── users.ts      # GET/POST /api/users\n│   │   └── users/\n│   │       └── [id].ts   # GET/PUT /api/users/:id\n│   ├── pages/            # Frontend pages\n│   │   ├── index.tsx     # GET /\n│   │   ├── about.tsx     # GET /about\n│   │   └── users.tsx     # GET /users\n│   ├── styles/           # Stylesheets\n│   │   └── app.css\n│   └── types/            # Shared types\n│       └── api.ts\n├── .vont/                # Framework internal files (auto-generated, git-ignored)\n│   └── client.tsx        # Generated client entry (don't edit)\n├── index.html            # HTML entry (optional)\n├── vont.config.ts        # Vont configuration (optional)\n├── .gitignore            # Should include .vont/\n└── package.json\n```\n\n\u003e **Important**: Add `.vont/` to your `.gitignore`:\n\u003e ```gitignore\n\u003e # Vont Framework generated files\n\u003e .vont/\n\u003e ```\n\n### 3. Create an API Route\n\n```typescript\n// src/api/users.ts\nimport type { Context } from 'koa';\n\nexport const get = async (ctx: Context) =\u003e {\n  ctx.body = { users: [] };\n};\n\nexport const post = async (ctx: Context) =\u003e {\n  const { name } = ctx.request.body;\n  ctx.body = { id: 1, name };\n  ctx.status = 201;\n};\n```\n\n### 4. Create a Page\n\n```typescript\n// src/pages/users.tsx\nimport React from 'react';\n\nconst UsersPage = () =\u003e {\n  return \u003cdiv\u003eUsers Page\u003c/div\u003e;\n};\n\nexport default UsersPage;\n```\n\n### 5. Start Development Server\n\n```bash\nnpm run dev\n```\n\nVisit `http://localhost:3000`\n\n## 🛠️ CLI Commands\n\n### `vont create`\n\nCreate a new Vont project with interactive prompts or command-line options.\n\n**Interactive Mode:**\n```bash\nvont create\n```\n\n**Quick Mode:**\n```bash\nvont create \u003cproject-name\u003e              # Prompts for template\nvont create \u003cproject-name\u003e --template \u003ctemplate\u003e  # Fully automated\n```\n\n**Available Templates:**\n- `react-ts` - React + TypeScript + React Router\n- `vue-ts` - Vue 3 + TypeScript + Vue Router\n\n**Examples:**\n```bash\n# Interactive (recommended for first-time users)\nvont create\n\n# With project name only\nvont create my-project\n\n# Fully automated (great for scripts/CI)\nvont create my-app --template react-ts\nvont create my-vue-app --template vue-ts\n\n# Flexible syntax\nvont create --template react-ts my-app\nvont create --template=vue-ts my-app\n```\n\n**Project Name Rules:**\n- ✅ Letters, numbers, hyphens, underscores\n- ❌ Spaces, special characters\n\n---\n\n### `vont dev`\n\nStart development server with hot module replacement.\n\n**Basic Usage:**\n```bash\nnpm run dev\n# or\nvont dev\n```\n\n**With Options:**\n```bash\nvont dev --port 4000              # Custom port\nvont dev --host 0.0.0.0          # Custom host\nvont dev --port 4000 --host localhost --open\n```\n\n**Options:**\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--port \u003cnumber\u003e` | Server port | `3000` |\n| `--host \u003cstring\u003e` | Server host | `0.0.0.0` |\n| `--open` | Open browser automatically | `false` |\n\n**Environment Variables:**\n```bash\nPORT=4000 HMR_PORT=4001 vont dev\n```\n\n**What Happens:**\n- ✅ API routes are compiled and served\n- ✅ Frontend served with Vite HMR\n- ✅ File watching enabled\n- ✅ Hot reload on changes\n- ✅ WebSocket for instant updates\n\n**Access:**\n- Frontend: `http://localhost:3000`\n- API: `http://localhost:3000/api/*`\n- HMR: `ws://localhost:3001`\n\n---\n\n### `vont build`\n\nBuild project for production.\n\n**Basic Usage:**\n```bash\nnpm run build\n# or\nvont build\n```\n\n**With Options:**\n```bash\nvont build --outDir dist          # Custom output directory\nvont build --mode production      # Build mode\n```\n\n**Options:**\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--outDir \u003cdir\u003e` | Output directory | `dist` |\n| `--mode \u003cmode\u003e` | Build mode | `production` |\n\n**Output Structure:**\n```\ndist/\n├── client/              # Frontend assets\n│   ├── assets/          # JS/CSS bundles\n│   │   ├── index-*.js\n│   │   └── index-*.css\n│   └── index.html       # Entry HTML\n├── server/              # Server code\n│   └── index.js         # Production server\n└── api/                 # API routes\n    ├── users.js\n    └── users/\n        └── [id].js\n```\n\n**Build Features:**\n- ✅ TypeScript compilation\n- ✅ Code minification\n- ✅ Tree shaking\n- ✅ Source maps\n- ✅ Asset optimization\n\n---\n\n### `vont start`\n\nStart production server.\n\n**Basic Usage:**\n```bash\nnpm run start\n# or\nvont start\n```\n\n**With Options:**\n```bash\nvont start --port 8080           # Custom port\nvont start --host 0.0.0.0        # Custom host\nPORT=8080 vont start             # Using environment variable\n```\n\n**Options:**\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--port \u003cnumber\u003e` | Server port | `3000` |\n| `--host \u003cstring\u003e` | Server host | `0.0.0.0` |\n\n**Prerequisites:**\n- Must run `vont build` first\n- `dist/` directory must exist\n\n**Production Features:**\n- ✅ Serves static files from `dist/client`\n- ✅ Handles API routes from `dist/api`\n- ✅ Optimized for performance\n- ✅ No HMR overhead\n\n---\n\n## 🎯 Complete Workflow Example\n\n### 1. Create Project\n\n```bash\n# Interactive creation\nnpx vont create\n? Project name: › my-fullstack-app\n? Select a framework: › React\n\ncd my-fullstack-app\nnpm install\n```\n\n### 2. Development\n\n```bash\n# Start development server\nnpm run dev\n```\n\n**Create an API route:** `src/api/todos.ts`\n```typescript\nimport type { Context } from 'koa';\n\ninterface Todo {\n  id: number;\n  title: string;\n  completed: boolean;\n}\n\nconst todos: Todo[] = [];\n\nexport const get = async (ctx: Context) =\u003e {\n  ctx.body = { data: todos };\n};\n\nexport const post = async (ctx: Context) =\u003e {\n  const { title } = ctx.request.body as { title: string };\n  const todo: Todo = {\n    id: Date.now(),\n    title,\n    completed: false,\n  };\n  todos.push(todo);\n  ctx.body = { data: todo };\n  ctx.status = 201;\n};\n```\n\n**Create a page:** `src/pages/todos.tsx`\n```typescript\nimport React, { useState, useEffect } from 'react';\n\ninterface Todo {\n  id: number;\n  title: string;\n  completed: boolean;\n}\n\nconst TodosPage: React.FC = () =\u003e {\n  const [todos, setTodos] = useState\u003cTodo[]\u003e([]);\n  const [title, setTitle] = useState('');\n\n  useEffect(() =\u003e {\n    fetchTodos();\n  }, []);\n\n  const fetchTodos = async () =\u003e {\n    const res = await fetch('/api/todos');\n    const { data } = await res.json();\n    setTodos(data);\n  };\n\n  const addTodo = async (e: React.FormEvent) =\u003e {\n    e.preventDefault();\n    const res = await fetch('/api/todos', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ title }),\n    });\n    const { data } = await res.json();\n    setTodos([...todos, data]);\n    setTitle('');\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eTodos\u003c/h1\u003e\n      \u003cform onSubmit={addTodo}\u003e\n        \u003cinput\n          value={title}\n          onChange={(e) =\u003e setTitle(e.target.value)}\n          placeholder=\"New todo\"\n        /\u003e\n        \u003cbutton type=\"submit\"\u003eAdd\u003c/button\u003e\n      \u003c/form\u003e\n      \u003cul\u003e\n        {todos.map(todo =\u003e (\n          \u003cli key={todo.id}\u003e{todo.title}\u003c/li\u003e\n        ))}\n      \u003c/ul\u003e\n    \u003c/div\u003e\n  );\n};\n\nexport default TodosPage;\n```\n\n**Access:**\n- Page: `http://localhost:3000/todos`\n- API: `http://localhost:3000/api/todos`\n\n### 3. Build for Production\n\n```bash\nnpm run build\n```\n\n### 4. Deploy\n\n```bash\n# Test production locally\nnpm run start\n\n# Or deploy to your server\nscp -r dist/ user@server:/app\nssh user@server \"cd /app \u0026\u0026 PORT=80 node dist/server/index.js\"\n```\n\n---\n\n## API Documentation\n\n### File-based Routing\n\n#### API Routes\n\nFiles in `src/api/` automatically become API endpoints:\n\n| File | Route |\n|------|-------|\n| `users.ts` | `/api/users` |\n| `users/[id].ts` | `/api/users/:id` |\n| `posts/[id]/comments.ts` | `/api/posts/:id/comments` |\n\n#### HTTP Methods\n\nExport functions named after HTTP methods:\n\n```typescript\nexport const get = async (ctx) =\u003e { /* GET handler */ };\nexport const post = async (ctx) =\u003e { /* POST handler */ };\nexport const put = async (ctx) =\u003e { /* PUT handler */ };\nexport const delete = async (ctx) =\u003e { /* DELETE handler */ };\nexport const patch = async (ctx) =\u003e { /* PATCH handler */ };\n```\n\n#### Middleware\n\nExport a `middleware` array to apply middleware to all routes in the file:\n\n```typescript\nimport type { Context, Next } from 'koa';\n\nexport const middleware = [\n  async (ctx: Context, next: Next) =\u003e {\n    // Authentication middleware\n    await next();\n  }\n];\n\nexport const get = async (ctx: Context) =\u003e {\n  // This route is protected by the middleware\n  ctx.body = { protected: true };\n};\n```\n\n### Configuration\n\nVont follows a **zero-configuration** approach - it works out of the box without any configuration file. However, you can customize behavior through configuration files when needed.\n\n#### Configuration Files\n\nVont automatically looks for configuration files in the following order:\n\n1. `vont.config.ts` (recommended)\n2. `vont.config.js`\n3. `vont.config.mjs`\n\nIf no configuration file is found, Vont uses sensible defaults.\n\n#### Basic Configuration (`vont.config.ts`)\n\n```typescript\nimport { defineConfig } from 'vont';\n\nexport default defineConfig({\n  // Server settings\n  port: 3000,\n  host: '0.0.0.0',\n  \n  // API configuration\n  apiPrefix: '/api',\n  apiDir: './src/api',\n  \n  // Pages configuration\n  pagesDir: './src/pages',\n  \n  // Output directory\n  outDir: './dist',\n});\n```\n\n#### Advanced Configuration\n\n```typescript\nimport { defineConfig } from 'vont';\nimport tailwindcss from '@tailwindcss/vite';\n\nexport default defineConfig({\n  // Basic settings\n  port: 4000,\n  host: '0.0.0.0',\n  apiPrefix: '/api/v1',\n  \n  // Complete Vite configuration (use native Vite config)\n  viteConfig: {\n    plugins: [\n      ...tailwindcss(),\n      ...react(),\n    ],\n    resolve: {\n      alias: {\n        '@': '/src',\n      },\n    },\n    optimizeDeps: {\n      include: ['react', 'react-dom'],\n    },\n  },\n  \n  // Server configuration\n  server: {\n    hmrPort: 3001,\n    middlewares: [\n      // Custom Koa middlewares\n    ],\n  },\n  \n  // Build configuration\n  build: {\n    sourcemap: true,\n    minify: true,\n    target: 'es2020',\n  },\n});\n```\n\n#### JavaScript Configuration (`vont.config.js`)\n\n```javascript\nexport default {\n  port: 3000,\n  apiPrefix: '/api',\n  viteConfig: {\n    plugins: [],\n  },\n};\n```\n\n#### Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `port` | `number` | `3000` | Server port |\n| `host` | `string` | `'0.0.0.0'` | Server host |\n| `apiPrefix` | `string` | `'/api'` | API route prefix |\n| `apiDir` | `string` | `'src/api'` | API directory path |\n| `pagesDir` | `string` | `'src/pages'` | Pages directory path |\n| `outDir` | `string` | `'dist'` | Build output directory |\n| `viteConfig` | `ViteConfig` | `{}` | Complete Vite configuration (including plugins) |\n| `server.hmrPort` | `number` | `3001` | HMR WebSocket port |\n| `server.middlewares` | `Middleware[]` | `[]` | Custom Koa middlewares |\n| `build.sourcemap` | `boolean` | `true` | Generate sourcemaps |\n| `build.minify` | `boolean` | `true` | Minify output |\n| `build.target` | `string` | `'es2020'` | Build target |\n\n#### Environment Variables\n\nYou can also configure Vont using environment variables:\n\n```bash\nPORT=4000 vont dev\nHOST=localhost vont dev\nHMR_PORT=4001 vont dev\n```\n\n#### Built-in Vite Configuration\n\nVont provides sensible defaults for Vite configuration, so you **don't need a separate `vite.config.ts`** file. All Vite settings are managed through the `viteConfig` field in `vont.config.ts`:\n\n**Default Vite Configuration:**\n\n- ✅ `server.middlewareMode: true` - For Koa integration\n- ✅ `server.hmr.port` - Automatically set from config\n- ✅ `server.watch.usePolling: false` - Optimized file watching\n- ✅ `build.outDir: 'dist/client'` - Client output directory\n- ✅ `build.rollupOptions.input: 'index.html'` - Entry point\n- ✅ `resolve.alias['@']: '/src'` - Path alias\n- ✅ `optimizeDeps.include: ['react', 'react-dom', 'react-router-dom']` - Pre-bundle dependencies\n\n**Use Native Vite Configuration:**\n\n```typescript\n// vont.config.ts\nimport { defineConfig } from 'vont';\nimport tailwindcss from '@tailwindcss/vite';\nimport react from '@vitejs/plugin-react';\n\nexport default defineConfig({\n  port: 3000,\n  \n  // Use complete native Vite configuration\n  viteConfig: {\n    // Vite plugins (use native Vite plugin config)\n    plugins: [\n      ...tailwindcss(),\n      ...react(),\n    ],\n    \n    // Add or override any Vite configuration\n    resolve: {\n      alias: {\n        '@components': '/src/components',\n      },\n    },\n    build: {\n      chunkSizeWarningLimit: 1000,\n    },\n  },\n});\n```\n\n\u003e **Note**: You no longer need to install `vite` as a project dependency. Vont includes it internally.\n\n### Type Safety\n\nShare types between frontend and backend:\n\n```typescript\n// src/types/api.ts\nexport interface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\n// src/api/users.ts\nimport type { User } from '../types/api';\n\nexport const get = async (ctx: Context) =\u003e {\n  const users: User[] = [];\n  ctx.body = { data: users };\n};\n\n// src/pages/users.tsx\nimport type { User } from '@/types/api';\n\nconst UsersPage = () =\u003e {\n  const [users, setUsers] = useState\u003cUser[]\u003e([]);\n  // ...\n};\n```\n\n## Programmatic API\n\n### Development Server\n\n#### `createDevServer(options)`\n\nCreate a development server programmatically:\n\n```typescript\nimport { createDevServer } from 'vont';\n\nawait createDevServer({\n  root: process.cwd(),\n  port: 3000,\n  host: '0.0.0.0',\n  hmrPort: 3001,\n  apiDir: './src/api',\n  pagesDir: './src/pages',\n});\n```\n\n**Options:**\n- `root` - Project root directory\n- `port` - Server port\n- `host` - Server host\n- `hmrPort` - Hot Module Replacement port\n- `apiDir` - API routes directory\n- `pagesDir` - Pages directory\n- `apiPrefix` - API route prefix\n\n### Production Server\n\n#### `createProdServer(options)` / `startProductionServer(options)`\n\nCreate a production server programmatically:\n\n```typescript\nimport { createProdServer } from 'vont';\n// or\nimport { startProductionServer } from 'vont';\n\nawait createProdServer({\n  root: process.cwd(),\n  port: 3000,\n  host: '0.0.0.0',\n});\n```\n\n**Options:**\n- `root` - Project root directory\n- `port` - Server port\n- `host` - Server host\n- `apiDir` - API routes directory (compiled)\n- `apiPrefix` - API route prefix\n\n### Build\n\n#### `buildProject(options)`\n\nBuild project programmatically:\n\n```typescript\nimport { buildProject } from 'vont';\n\nawait buildProject({\n  root: process.cwd(),\n  outDir: 'dist',\n  apiDir: './src/api',\n});\n```\n\n**Options:**\n- `root` - Project root directory\n- `outDir` - Output directory\n- `apiDir` - API routes directory\n- `serverDir` - Server output directory\n\n### Configuration Loader\n\n#### `loadConfig(rootDir)`\n\nLoad Vont configuration from project:\n\n```typescript\nimport { loadConfig } from 'vont';\n\nconst config = await loadConfig(process.cwd());\nconsole.log(config.port); // 3000\n```\n\n#### `defineConfig(config)`\n\nType-safe configuration helper:\n\n```typescript\nimport { defineConfig } from 'vont';\n\nexport default defineConfig({\n  port: 3000,\n  // Full TypeScript autocompletion\n});\n```\n\n## Examples\n\n### Dynamic Routes\n\n```typescript\n// src/api/posts/[id].ts\nimport type { Context } from 'koa';\n\nexport const get = async (ctx: Context) =\u003e {\n  const { id } = ctx.params;\n  ctx.body = { id, title: 'Post Title' };\n};\n\nexport const put = async (ctx: Context) =\u003e {\n  const { id } = ctx.params;\n  const { title } = ctx.request.body;\n  ctx.body = { id, title };\n};\n\nexport const delete = async (ctx: Context) =\u003e {\n  const { id } = ctx.params;\n  ctx.status = 204; // No Content\n};\n```\n\n### Query Parameters\n\n```typescript\n// src/api/search.ts\nimport type { Context } from 'koa';\n\nexport const get = async (ctx: Context) =\u003e {\n  const { q, page = '1', limit = '10' } = ctx.query;\n  \n  ctx.body = {\n    query: q,\n    page: parseInt(page as string),\n    limit: parseInt(limit as string),\n    results: [],\n  };\n};\n```\n\n### Request Body\n\n```typescript\n// src/api/users.ts\nimport type { Context } from 'koa';\n\nexport const post = async (ctx: Context) =\u003e {\n  const { name, email } = ctx.request.body;\n  \n  // Validation\n  if (!name || !email) {\n    ctx.status = 400;\n    ctx.body = { error: 'Name and email are required' };\n    return;\n  }\n  \n  // Create user\n  const user = { id: Date.now(), name, email };\n  ctx.body = user;\n  ctx.status = 201;\n};\n```\n\n### Error Handling\n\n```typescript\n// src/api/users/[id].ts\nimport type { Context } from 'koa';\n\nexport const get = async (ctx: Context) =\u003e {\n  const { id } = ctx.params;\n  \n  try {\n    // Fetch user from database\n    const user = await db.users.findById(id);\n    \n    if (!user) {\n      ctx.status = 404;\n      ctx.body = { error: 'User not found' };\n      return;\n    }\n    \n    ctx.body = user;\n  } catch (error) {\n    ctx.status = 500;\n    ctx.body = { error: 'Internal server error' };\n    console.error(error);\n  }\n};\n```\n\n### Authentication Middleware\n\n```typescript\n// src/api/protected.ts\nimport type { Context, Next } from 'koa';\n\n// Authentication middleware\nexport const middleware = [\n  async (ctx: Context, next: Next) =\u003e {\n    const token = ctx.headers.authorization?.split(' ')[1];\n    \n    if (!token) {\n      ctx.status = 401;\n      ctx.body = { error: 'Unauthorized' };\n      return;\n    }\n    \n    try {\n      // Verify token\n      ctx.state.user = await verifyToken(token);\n      await next();\n    } catch (error) {\n      ctx.status = 401;\n      ctx.body = { error: 'Invalid token' };\n    }\n  },\n];\n\n// Protected route\nexport const get = async (ctx: Context) =\u003e {\n  ctx.body = {\n    message: 'Protected data',\n    user: ctx.state.user,\n  };\n};\n```\n\n### Nested Dynamic Routes\n\n```typescript\n// src/api/posts/[postId]/comments/[commentId].ts\nimport type { Context } from 'koa';\n\nexport const get = async (ctx: Context) =\u003e {\n  const { postId, commentId } = ctx.params;\n  ctx.body = {\n    postId,\n    commentId,\n    content: 'Comment content',\n  };\n};\n```\n\n### File Upload\n\n```typescript\n// src/api/upload.ts\nimport type { Context } from 'koa';\nimport formidable from 'formidable';\n\nexport const post = async (ctx: Context) =\u003e {\n  const form = formidable({ multiples: true });\n  \n  const [fields, files] = await form.parse(ctx.req);\n  \n  ctx.body = {\n    fields,\n    files,\n  };\n};\n```\n\n## Development\n\n### Hot Reload Features\n\nVont provides comprehensive hot reload capabilities for both frontend and backend:\n\n- **Frontend HMR** - React Fast Refresh for instant component updates\n- **CSS Hot Update** - Style changes apply immediately without page refresh\n- **Backend Auto-Restart** - Server restarts automatically when server code changes\n- **API Hot Reload** - API routes reload dynamically without full server restart\n- **TypeScript Support** - Full TypeScript hot reload with `tsx` loader\n\n### Development Workflow\n\n```bash\n# Start development server\nnpm run dev\n\n# Development server starts at http://localhost:3000\n# HMR WebSocket at ws://localhost:3001\n\n# Make changes to:\n# - src/pages/*.tsx -\u003e React Fast Refresh (instant)\n# - src/styles/*.css -\u003e CSS hot update (instant)\n# - src/api/*.ts -\u003e API hot reload (~500ms)\n# - src/server/*.ts -\u003e Server restart (~1-2s)\n```\n\n### Performance\n\n| Feature | Traditional Approach | Vont |\n|---------|---------------------|------|\n| Startup Time | 10-30s (build + start) | \u003c 2s (direct execution) |\n| Frontend Updates | Manual refresh | HMR (instant) |\n| CSS Changes | Full reload | Hot update (instant) |\n| Backend Updates | Manual restart (~10s) | Auto-restart (~1-2s) |\n| API Updates | Manual restart (~10s) | Hot reload (~500ms) |\n\n### Debug Tips\n\n#### Enable Verbose Logging\n\n```bash\n# Show detailed logs\nDEBUG=vont:* npm run dev\n```\n\n#### TypeScript Errors\n\n```bash\n# Type checking (no emit)\nnpm run type-check\n\n# Watch mode\ntsc --noEmit --watch\n```\n\n#### Port Conflicts\n\n```bash\n# Use different ports\nPORT=4000 HMR_PORT=4001 npm run dev\n```\n\n#### API Hot Reload Not Working\n\n- Ensure API files are in `src/api/` directory\n- Check file naming follows convention (`.ts` extension)\n- Verify exports are named correctly (`get`, `post`, etc.)\n\n#### HMR Not Working\n\n- Check if port 3001 is available (or custom `hmrPort`)\n- Verify Vite configuration has `middlewareMode: true`\n- Check browser console for WebSocket errors\n\n## Deployment\n\n### Building for Production\n\n```bash\nnpm run build\n```\n\nThis generates:\n```\ndist/\n├── client/          # Frontend assets (served by Koa)\n│   ├── assets/\n│   └── index.html\n├── server/          # Compiled server\n│   └── index.js\n└── api/             # Compiled API routes\n    └── users.js\n```\n\n\u003e **Note**: The `.vont/` directory is automatically cleaned up after build and should not be included in production deployments.\n\n### Starting Production Server\n\n```bash\nnpm run start\n\n# Or with custom settings\nPORT=8080 npm run start\n```\n\n### Docker Deployment\n\n```dockerfile\nFROM node:18-alpine\n\nWORKDIR /app\n\n# Copy package files\nCOPY package*.json ./\n\n# Install dependencies\nRUN npm ci --only=production\n\n# Copy built files\nCOPY dist ./dist\n\n# Expose port\nEXPOSE 3000\n\n# Start server\nCMD [\"node\", \"dist/server/index.js\"]\n```\n\n### Environment Variables\n\n```bash\n# .env.production\nPORT=8080\nHOST=0.0.0.0\nNODE_ENV=production\n```\n\n### Nginx Reverse Proxy\n\n```nginx\nserver {\n  listen 80;\n  server_name example.com;\n\n  location / {\n    proxy_pass http://localhost:3000;\n    proxy_http_version 1.1;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection 'upgrade';\n    proxy_set_header Host $host;\n    proxy_cache_bypass $http_upgrade;\n  }\n}\n```\n\n## Troubleshooting\n\n### Common Issues\n\n#### Module not found errors\n\n```bash\n# Clear node_modules and reinstall\nrm -rf node_modules package-lock.json\nnpm install\n```\n\n#### Build fails\n\n```bash\n# Check TypeScript errors\nnpm run type-check\n\n# Clean build and retry\nrm -rf dist\nnpm run build\n```\n\n#### API routes not working\n\n- Verify file structure matches convention\n- Check exports are named correctly\n- Ensure `apiPrefix` in config matches requests\n- Check server logs for route registration\n\n#### 404 on page routes\n\n- Verify page files are in `src/pages/`\n- Check file exports default React component\n- Ensure no TypeScript errors in page files\n\n### Getting Help\n\n- Check [Documentation](https://vont.dev)\n- Search [GitHub Issues](https://github.com/yourusername/vont/issues)\n- Join [Discord Community](https://discord.gg/vont)\n\n## FAQ\n\n**Q: Do I need both `vont.config.ts` and `vite.config.ts`?**  \nA: No, `vont.config.ts` is sufficient for most cases. Use `vite.config.ts` only for advanced Vite-specific features.\n\n**Q: What is the `.vont/` directory?**  \nA: It's an auto-generated directory containing framework internal files (like `client.tsx`). It's automatically created during development and cleaned up when not needed. Always add it to your `.gitignore`.\n\n**Q: Can I edit files in `.vont/` directory?**  \nA: No, don't edit these files manually. They are auto-generated by Vont and will be overwritten. If you need to customize client behavior, use `vont.config.ts`.\n\n**Q: Can I use other CSS frameworks?**  \nA: Yes! Vont works with any CSS solution: CSS Modules, Styled Components, Emotion, Tailwind CSS, etc.\n\n**Q: Does Vont support Server-Side Rendering (SSR)?**  \nA: Not yet. Vont currently focuses on SPA with API routes. \n\n**Q: Can I deploy to serverless platforms?**  \nA: Not recommended. Vont uses file-based routing which requires a Node.js server. Best deployed on traditional hosting (VPS, Docker, etc.).\n\n**Q: How do I add database support?**  \nA: Install your preferred ORM/database client and use it in API routes:\n```typescript\nimport { db } from '@/lib/db';\n\nexport const get = async (ctx) =\u003e {\n  const users = await db.users.findMany();\n  ctx.body = { users };\n};\n```\n\n};\n```\n\n## 💡 Best Practices \u0026 Tips\n\n### Project Organization\n\n**Recommended Structure:**\n```\nsrc/\n├── api/                   # Backend API routes\n│   ├── auth/\n│   │   ├── login.ts      # POST /api/auth/login\n│   │   └── logout.ts     # POST /api/auth/logout\n│   ├── users/\n│   │   ├── index.ts      # GET/POST /api/users\n│   │   └── [id].ts       # GET/PUT/DELETE /api/users/:id\n│   └── posts/\n│       └── [id]/\n│           └── comments.ts # GET /api/posts/:id/comments\n├── pages/                 # Frontend pages\n│   ├── index.tsx         # Home page\n│   ├── about.tsx         # About page\n│   ├── users.tsx         # Users list\n│   └── users/\n│       └── [id].tsx      # User detail (future feature)\n├── components/            # Shared React/Vue components\n│   ├── Header.tsx\n│   ├── Footer.tsx\n│   └── Button.tsx\n├── lib/                   # Utility functions\n│   ├── api.ts            # API client\n│   ├── auth.ts           # Auth helpers\n│   └── utils.ts          # Common utilities\n├── types/                 # TypeScript types\n│   ├── api.ts            # API types\n│   └── models.ts         # Data models\n└── styles/               # CSS files\n    ├── app.css           # Global styles\n    └── components.css    # Component styles\n```\n\n### Type Safety Tips\n\n**Share types between frontend and backend:**\n\n```typescript\n// src/types/api.ts\nexport interface User {\n  id: number;\n  name: string;\n  email: string;\n  createdAt: string;\n}\n\nexport interface ApiResponse\u003cT\u003e {\n  data: T;\n  error?: string;\n}\n\n// src/api/users.ts\nimport type { Context } from 'koa';\nimport type { User, ApiResponse } from '../types/api';\n\nexport const get = async (ctx: Context) =\u003e {\n  const users: User[] = await db.users.findMany();\n  const response: ApiResponse\u003cUser[]\u003e = { data: users };\n  ctx.body = response;\n};\n\n// src/pages/users.tsx\nimport type { User, ApiResponse } from '@/types/api';\n\nconst UsersPage = () =\u003e {\n  const [users, setUsers] = useState\u003cUser[]\u003e([]);\n  \n  const fetchUsers = async () =\u003e {\n    const res = await fetch('/api/users');\n    const json: ApiResponse\u003cUser[]\u003e = await res.json();\n    setUsers(json.data);\n  };\n};\n```\n\n### API Development Tips\n\n**1. Use Middleware for Common Logic:**\n\n```typescript\n// src/api/auth/middleware.ts\nimport type { Context, Next } from 'koa';\n\nexport const authMiddleware = async (ctx: Context, next: Next) =\u003e {\n  const token = ctx.headers.authorization?.replace('Bearer ', '');\n  \n  if (!token) {\n    ctx.status = 401;\n    ctx.body = { error: 'Unauthorized' };\n    return;\n  }\n  \n  try {\n    ctx.state.user = await verifyToken(token);\n    await next();\n  } catch (error) {\n    ctx.status = 401;\n    ctx.body = { error: 'Invalid token' };\n  }\n};\n\n// src/api/protected-route.ts\nimport { authMiddleware } from './auth/middleware';\n\nexport const middleware = [authMiddleware];\n\nexport const get = async (ctx: Context) =\u003e {\n  const user = ctx.state.user;\n  ctx.body = { data: `Hello ${user.name}` };\n};\n```\n\n**2. Error Handling Pattern:**\n\n```typescript\n// src/lib/errors.ts\nexport class ApiError extends Error {\n  constructor(\n    public status: number,\n    public message: string\n  ) {\n    super(message);\n  }\n}\n\n// src/api/users/[id].ts\nimport { ApiError } from '@/lib/errors';\n\nexport const get = async (ctx: Context) =\u003e {\n  try {\n    const { id } = ctx.params;\n    const user = await db.users.findById(id);\n    \n    if (!user) {\n      throw new ApiError(404, 'User not found');\n    }\n    \n    ctx.body = { data: user };\n  } catch (error) {\n    if (error instanceof ApiError) {\n      ctx.status = error.status;\n      ctx.body = { error: error.message };\n    } else {\n      ctx.status = 500;\n      ctx.body = { error: 'Internal server error' };\n      console.error(error);\n    }\n  }\n};\n```\n\n**3. Request Validation:**\n\n```typescript\n// src/api/users.ts\nimport { z } from 'zod';\n\nconst createUserSchema = z.object({\n  name: z.string().min(1).max(100),\n  email: z.string().email(),\n  age: z.number().min(18).optional(),\n});\n\nexport const post = async (ctx: Context) =\u003e {\n  try {\n    const data = createUserSchema.parse(ctx.request.body);\n    const user = await db.users.create(data);\n    ctx.body = { data: user };\n    ctx.status = 201;\n  } catch (error) {\n    if (error instanceof z.ZodError) {\n      ctx.status = 400;\n      ctx.body = { error: 'Validation failed', details: error.errors };\n    } else {\n      ctx.status = 500;\n      ctx.body = { error: 'Internal server error' };\n    }\n  }\n};\n```\n\n### Frontend Development Tips\n\n**1. Create a Type-Safe API Client:**\n\n```typescript\n// src/lib/api.ts\nexport class ApiClient {\n  private baseUrl = '/api';\n\n  async get\u003cT\u003e(path: string): Promise\u003cT\u003e {\n    const res = await fetch(`${this.baseUrl}${path}`);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return res.json();\n  }\n\n  async post\u003cT\u003e(path: string, data: unknown): Promise\u003cT\u003e {\n    const res = await fetch(`${this.baseUrl}${path}`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(data),\n    });\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return res.json();\n  }\n\n  // Add put, delete, patch methods...\n}\n\nexport const api = new ApiClient();\n\n// Usage in components\nimport { api } from '@/lib/api';\nimport type { ApiResponse, User } from '@/types/api';\n\nconst users = await api.get\u003cApiResponse\u003cUser[]\u003e\u003e('/users');\n```\n\n**2. Environment Variables:**\n\n```typescript\n// vite.config.ts (if needed)\nexport default defineConfig({\n  define: {\n    'import.meta.env.API_URL': JSON.stringify(process.env.API_URL),\n  },\n});\n\n// Usage\nconst apiUrl = import.meta.env.API_URL || '/api';\n```\n\n### Performance Optimization\n\n**1. Code Splitting:**\n\n```typescript\n// src/pages/index.tsx\nimport { lazy, Suspense } from 'react';\n\nconst HeavyComponent = lazy(() =\u003e import('@/components/HeavyComponent'));\n\nexport default () =\u003e (\n  \u003cSuspense fallback={\u003cdiv\u003eLoading...\u003c/div\u003e}\u003e\n    \u003cHeavyComponent /\u003e\n  \u003c/Suspense\u003e\n);\n```\n\n**2. API Response Caching:**\n\n```typescript\n// src/lib/cache.ts\nconst cache = new Map\u003cstring, { data: unknown; expires: number }\u003e();\n\nexport async function cachedFetch\u003cT\u003e(\n  url: string,\n  ttl: number = 60000\n): Promise\u003cT\u003e {\n  const cached = cache.get(url);\n  if (cached \u0026\u0026 cached.expires \u003e Date.now()) {\n    return cached.data as T;\n  }\n\n  const res = await fetch(url);\n  const data = await res.json();\n  cache.set(url, { data, expires: Date.now() + ttl });\n  return data;\n}\n```\n\n### Development Workflow\n\n**1. Hot Reload Workflow:**\n```bash\n# Terminal 1: Development server\nnpm run dev\n\n# Terminal 2: Type checking (optional)\ntsc --noEmit --watch\n\n# Make changes to:\n# - src/api/*.ts -\u003e API reloads (~500ms)\n# - src/pages/*.tsx -\u003e HMR (~50ms)\n# - src/styles/*.css -\u003e HMR (~50ms)\n```\n\n**2. Pre-commit Checks:**\n\n```json\n// package.json\n{\n  \"scripts\": {\n    \"dev\": \"vont dev\",\n    \"build\": \"vont build\",\n    \"start\": \"vont start\",\n    \"type-check\": \"tsc --noEmit\",\n    \"lint\": \"eslint src/\",\n    \"test\": \"vitest\",\n    \"precommit\": \"npm run type-check \u0026\u0026 npm run lint\"\n  }\n}\n```\n\n### Common Patterns\n\n**1. Protected Routes (Frontend):**\n\n```typescript\n// src/components/ProtectedRoute.tsx\nimport { Navigate } from 'react-router-dom';\nimport { useAuth } from '@/lib/auth';\n\nexport const ProtectedRoute = ({ children }: { children: React.ReactNode }) =\u003e {\n  const { user, loading } = useAuth();\n\n  if (loading) return \u003cdiv\u003eLoading...\u003c/div\u003e;\n  if (!user) return \u003cNavigate to=\"/login\" replace /\u003e;\n\n  return \u003c\u003e{children}\u003c/\u003e;\n};\n\n// Usage\nimport { ProtectedRoute } from '@/components/ProtectedRoute';\n\n\u003cRoute \n  path=\"/dashboard\" \n  element={\n    \u003cProtectedRoute\u003e\n      \u003cDashboard /\u003e\n    \u003c/ProtectedRoute\u003e\n  } \n/\u003e\n```\n\n**2. File Upload:**\n\n```typescript\n// src/api/upload.ts\nimport formidable from 'formidable';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nexport const post = async (ctx: Context) =\u003e {\n  const form = formidable({ uploadDir: './uploads', keepExtensions: true });\n  const [fields, files] = await form.parse(ctx.req);\n  \n  ctx.body = { \n    data: { \n      filename: files.file[0].originalFilename,\n      path: files.file[0].filepath \n    } \n  };\n};\n```\n\n**3. Database Integration:**\n\n```typescript\n// src/lib/db.ts (Prisma example)\nimport { PrismaClient } from '@prisma/client';\n\nexport const db = new PrismaClient();\n\n// src/api/users.ts\nimport { db } from '@/lib/db';\n\nexport const get = async (ctx: Context) =\u003e {\n  const users = await db.user.findMany();\n  ctx.body = { data: users };\n};\n```\n\n---\n\n## Roadmap\n\n### Completed ✅\n- [x] File-based routing for API and pages\n- [x] Hot Module Replacement (HMR)\n- [x] TypeScript support\n- [x] React and Vue support\n- [x] **CLI project scaffolding (`vont create`)** - ⭐ New!\n- [x] Interactive project creation\n- [x] Production build optimization\n- [x] Zero-configuration setup\n\n### In Progress 🚧\n- [ ] Server-Side Rendering (SSR)\n- [ ] API route middleware composition improvements\n- [ ] Built-in authentication helpers\n\n### Planned 📋\n- [ ] Database adapters (Prisma, Drizzle integration)\n- [ ] Plugin system\n- [ ] WebSocket support\n- [ ] GraphQL support\n- [ ] Deployment adapters (Vercel, Cloudflare, Docker)\n- [ ] CLI enhancements (migration tools, generators)\n- [ ] Testing utilities\n- [ ] Documentation site\n\n## License\n\nMIT\n\n## Links\n\n- [GitHub](https://github.com/yourusername/vont)\n- [Documentation](https://vont.dev)\n- [Examples](https://github.com/yourusername/vont/tree/main/examples)\n- [Discord Community](https://discord.gg/vont)\n\n## Contributing\n\nContributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.\n\n## Acknowledgments\n\nBuilt with:\n- [Koa](https://koajs.com/) - Backend framework\n- [React](https://react.dev/) - Frontend library\n- [Vite](https://vitejs.dev/) - Build tool\n- [esbuild](https://esbuild.github.io/) - API compiler\n- [TypeScript](https://www.typescriptlang.org/) - Type safety\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkorbinjoe%2Fvontjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkorbinjoe%2Fvontjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkorbinjoe%2Fvontjs/lists"}