{"_id":"@darioh/byof","_rev":"4-d6434c5168bcc08ff77b112e5670de5a","name":"@darioh/byof","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@darioh/byof","version":"0.1.0","keywords":["frontend","ui","generator","openapi","chat","ai","html","sandbox","typescript","llm"],"author":{"name":"Dario Hefti"},"license":"MIT","_id":"@darioh/byof@0.1.0","maintainers":[{"name":"hdario","email":"dario.hefti@bluewin.ch"}],"homepage":"https://github.com/DarioHefti/byof#readme","bugs":{"url":"https://github.com/DarioHefti/byof/issues"},"dist":{"shasum":"33635c7f4a2196a6227a35d08f9bdaab297954ed","tarball":"https://registry.npmjs.org/@darioh/byof/-/byof-0.1.0.tgz","fileCount":13,"integrity":"sha512-cbkQr7RIvEku56C+zLU47jma4Qzyzv7nq0/o1JxjbGw0aQAJpPJQRymwsJjAc4IWqJZWOn1UEczfawK3CAnx6g==","signatures":[{"sig":"MEUCIEw5cNKTFseqMYz/ToTrRz5l4GbFLbnqZAASfAgRY4CFAiEA5mHU8YlNVK1Lp4+EzoblbeLpZXeJasX5037timhC2cU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1127442},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"92a16ee701d22e3d4211eefb2cfe0c88ab925e13","scripts":{"dev":"tsup --watch","lint":"eslint src","test":"vitest","build":"tsup","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","example":"concurrently -n web,api,build -c blue,green,yellow \"npm run example:web\" \"npm run example:api\" \"npm run dev\"","release":"npm run prepublishOnly && npm publish --access public","lint:fix":"eslint src --fix","test:run":"vitest run","typecheck":"tsc --noEmit","example:api":"node examples/backend/server.js","example:web":"npx serve examples/vanilla -l 3000","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run lint && npm run typecheck && npm run test:run && npm run build"},"_npmUser":{"name":"hdario","email":"dario.hefti@bluewin.ch"},"repository":{"url":"git+https://github.com/DarioHefti/byof.git","type":"git"},"_npmVersion":"11.7.0","description":"Bring Your Own Frontend - Chat-based UI generator from OpenAPI specs","directories":{"example":"examples"},"sideEffects":false,"_nodeVersion":"25.3.0","dependencies":{"zod":"^3.25.76"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^27.4.0","serve":"^14.2.5","eslint":"^9.39.2","vitest":"^4.0.17","prettier":"^3.8.0","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.9","@types/jsdom":"^27.0.0","concurrently":"^9.2.1","typescript-eslint":"^8.53.0","@vitest/coverage-v8":"^4.0.17","eslint-plugin-import":"^2.32.0","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.53.0","@typescript-eslint/eslint-plugin":"^8.53.0","eslint-import-resolver-typescript":"^4.4.4"},"_npmOperationalInternal":{"tmp":"tmp/byof_0.1.0_1768665495500_0.5717534836961726","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@darioh/byof","version":"0.1.1","keywords":["frontend","ui","generator","openapi","chat","ai","html","sandbox","typescript","llm"],"author":{"name":"Dario Hefti"},"license":"MIT","_id":"@darioh/byof@0.1.1","maintainers":[{"name":"hdario","email":"dario.hefti@bluewin.ch"}],"homepage":"https://github.com/DarioHefti/byof#readme","bugs":{"url":"https://github.com/DarioHefti/byof/issues"},"dist":{"shasum":"ed570149f30cdad780ebcdfff7941554929b4bea","tarball":"https://registry.npmjs.org/@darioh/byof/-/byof-0.1.1.tgz","fileCount":13,"integrity":"sha512-FDz+Sk4EKPb+A0faO778HbgucFlNnMHKR32qm8bABhQC8KS7zeYgaxx5Na0QIkHrEdc4WeENIUgDtOX6WlfHYA==","signatures":[{"sig":"MEUCIQD54TMgduRIVvkk7PC60NUefHD8HBhFu0XzQFE8gzqhqwIgHKFxHLtY2utTfqDmEMiXdJtI8U9HzUaPhbR4UuleyRg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1129112},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"6c39651fc8bebf4675fb32327c5f25a23bca5b31","scripts":{"dev":"tsup --watch","lint":"eslint src","test":"vitest","build":"tsup","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","example":"concurrently -n web,api,build -c blue,green,yellow \"npm run example:web\" \"npm run example:api\" \"npm run dev\"","release":"npm run prepublishOnly && npm publish --access public","lint:fix":"eslint src --fix","test:run":"vitest run","typecheck":"tsc --noEmit","example:api":"node examples/backend/server.js","example:web":"npx serve examples/vanilla -l 3000","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run lint && npm run typecheck && npm run test:run && npm run build"},"_npmUser":{"name":"hdario","email":"dario.hefti@bluewin.ch"},"repository":{"url":"git+https://github.com/DarioHefti/byof.git","type":"git"},"_npmVersion":"11.7.0","description":"Bring Your Own Frontend - Chat-based UI generator from OpenAPI specs","directories":{"example":"examples"},"sideEffects":false,"_nodeVersion":"25.3.0","dependencies":{"zod":"^3.25.76"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^27.4.0","serve":"^14.2.5","eslint":"^9.39.2","vitest":"^4.0.17","prettier":"^3.8.0","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.9","@types/jsdom":"^27.0.0","concurrently":"^9.2.1","typescript-eslint":"^8.53.0","@vitest/coverage-v8":"^4.0.17","eslint-plugin-import":"^2.32.0","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.53.0","@typescript-eslint/eslint-plugin":"^8.53.0","eslint-import-resolver-typescript":"^4.4.4"},"_npmOperationalInternal":{"tmp":"tmp/byof_0.1.1_1768924012172_0.3050016400763371","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@darioh/byof","version":"0.1.2","keywords":["frontend","ui","generator","openapi","chat","ai","html","sandbox","typescript","llm"],"author":{"name":"Dario Hefti"},"license":"MIT","_id":"@darioh/byof@0.1.2","maintainers":[{"name":"hdario","email":"dario.hefti@bluewin.ch"}],"homepage":"https://github.com/DarioHefti/byof#readme","bugs":{"url":"https://github.com/DarioHefti/byof/issues"},"dist":{"shasum":"fbeb5f300f2a013d0c990033ab52848962acac75","tarball":"https://registry.npmjs.org/@darioh/byof/-/byof-0.1.2.tgz","fileCount":13,"integrity":"sha512-//htjSdlGj7DTaaw8PnVUAup2qlLaWtvbpZZ9tVYwduxkEx/Jp/iJWKvJ2MK8RbChMtsoYWHVED/PGI9cQ9MPg==","signatures":[{"sig":"MEQCIDI4uppLoEpaVzInic0UNzZDyAvc/a7h9PBtJD7Po3TWAiBab6q6fr51zkBNre8T8QXIkJiBw0w282i1oAdmpbPo9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1193239},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18.0.0"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"f3fa3ebd4184df3df25d0234e5777207726f8bd6","scripts":{"dev":"tsup --watch","lint":"eslint src","test":"vitest","build":"tsup","clean":"rm -rf dist","format":"prettier --write \"src/**/*.ts\"","example":"concurrently -n web,api,build -c blue,green,yellow \"npm run example:web\" \"npm run example:api\" \"npm run dev\"","release":"npm run prepublishOnly && npm publish --access public","lint:fix":"eslint src --fix","test:run":"vitest run","typecheck":"tsc --noEmit","example:api":"node --env-file=examples/backend/.env examples/backend/server.js","example:web":"npx serve . -l 3000","format:check":"prettier --check \"src/**/*.ts\"","test:coverage":"vitest run --coverage","prepublishOnly":"npm run clean && npm run lint && npm run typecheck && npm run test:run && npm run build"},"_npmUser":{"name":"hdario","email":"dario.hefti@bluewin.ch"},"repository":{"url":"git+https://github.com/DarioHefti/byof.git","type":"git"},"_npmVersion":"11.7.0","description":"Bring Your Own Frontend - Chat-based UI generator from OpenAPI specs","directories":{"example":"examples"},"sideEffects":false,"_nodeVersion":"25.3.0","dependencies":{"zod":"^3.25.76"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","jsdom":"^27.4.0","serve":"^14.2.5","eslint":"^9.39.2","vitest":"^4.0.17","prettier":"^3.8.0","@eslint/js":"^9.39.2","typescript":"^5.9.3","@types/node":"^25.0.9","@types/jsdom":"^27.0.0","concurrently":"^9.2.1","typescript-eslint":"^8.53.0","@vitest/coverage-v8":"^4.0.17","eslint-plugin-import":"^2.32.0","eslint-config-prettier":"^10.1.8","@typescript-eslint/parser":"^8.53.0","@typescript-eslint/eslint-plugin":"^8.53.0","eslint-import-resolver-typescript":"^4.4.4"},"_npmOperationalInternal":{"tmp":"tmp/byof_0.1.2_1769531921355_0.03322032879642789","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@darioh/byof","version":"0.1.3","description":"Bring Your Own Frontend - Chat-based UI generator from OpenAPI specs","keywords":["frontend","ui","generator","openapi","chat","ai","html","sandbox","typescript","llm"],"homepage":"https://github.com/DarioHefti/byof#readme","bugs":{"url":"https://github.com/DarioHefti/byof/issues"},"repository":{"type":"git","url":"git+https://github.com/DarioHefti/byof.git"},"license":"MIT","author":{"name":"Dario Hefti"},"type":"module","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"main":"./dist/index.cjs","types":"./dist/index.d.ts","directories":{"example":"examples"},"scripts":{"build":"tsup","dev":"tsup --watch","lint":"eslint src","lint:fix":"eslint src --fix","format":"prettier --write \"src/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\"","test":"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","typecheck":"tsc --noEmit","example:web":"npx serve . -l 3000","example:api":"node --env-file=examples/backend/.env examples/backend/server.js","example":"concurrently -n web,api,build -c blue,green,yellow \"npm run example:web\" \"npm run example:api\" \"npm run dev\"","clean":"rm -rf dist","prepublishOnly":"npm run clean && npm run lint && npm run typecheck && npm run test:run && npm run build","release":"npm run prepublishOnly && npm publish --access public"},"dependencies":{"zod":"^3.25.76"},"devDependencies":{"@eslint/js":"^9.39.2","@types/jsdom":"^27.0.0","@types/node":"^25.0.9","@typescript-eslint/eslint-plugin":"^8.53.0","@typescript-eslint/parser":"^8.53.0","@vitest/coverage-v8":"^4.0.17","concurrently":"^9.2.1","eslint":"^9.39.2","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.4","eslint-plugin-import":"^2.32.0","jsdom":"^27.4.0","prettier":"^3.8.0","serve":"^14.2.5","tsup":"^8.5.1","typescript":"^5.9.3","typescript-eslint":"^8.53.0","vitest":"^4.0.17"},"engines":{"node":">=18.0.0"},"module":"./dist/index.js","sideEffects":false,"gitHead":"66e48e7d0144c448ce1f88866ad11296bf48e69e","_id":"@darioh/byof@0.1.3","_nodeVersion":"25.3.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-IJOfVXoN8NiRxRsZtUWeNnt9gynVHm+OpgdYOq4YqCKPePQgW4/xkTw1zPMd2RLUVdslRlH0tCp0V5TGM3CfqQ==","shasum":"58b176a14218ef83e19ddc4808a02fa7e7b04135","tarball":"https://registry.npmjs.org/@darioh/byof/-/byof-0.1.3.tgz","fileCount":13,"unpackedSize":1201314,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQClazucx7gSVKSgJk11wQYq2uPsjNv2mkooaHPzqqFvqAIge+qhqPCdmdZF/5/MdvJ6jVGfLNMr3B2rUK5SbjvBfM8="}]},"_npmUser":{"name":"hdario","email":"dario.hefti@bluewin.ch"},"maintainers":[{"name":"hdario","email":"dario.hefti@bluewin.ch"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/byof_0.1.3_1769674952234_0.959013922317882"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-17T15:58:15.402Z","modified":"2026-01-29T08:22:32.550Z","0.1.0":"2026-01-17T15:58:15.690Z","0.1.1":"2026-01-20T15:46:52.396Z","0.1.2":"2026-01-27T16:38:41.580Z","0.1.3":"2026-01-29T08:22:32.433Z"},"bugs":{"url":"https://github.com/DarioHefti/byof/issues"},"author":{"name":"Dario Hefti"},"license":"MIT","homepage":"https://github.com/DarioHefti/byof#readme","keywords":["frontend","ui","generator","openapi","chat","ai","html","sandbox","typescript","llm"],"repository":{"type":"git","url":"git+https://github.com/DarioHefti/byof.git"},"description":"Bring Your Own Frontend - Chat-based UI generator from OpenAPI specs","maintainers":[{"name":"hdario","email":"dario.hefti@bluewin.ch"}],"readme":"# BYOF\n\n**Bring Your Own Frontend** - A TypeScript library that lets users generate custom UIs through AI chat.\n\n## Installation\n\n```bash\nnpm install byof\n```\n\n## Quick Start\n\n```typescript\nimport { createByof } from 'byof'\n\nconst byof = createByof({\n  mount: document.getElementById('app')!,\n  chatEndpoint: '/api/chat',\n  onHtmlGenerated: (html) => console.log('Generated!'),\n})\n\n// Later: cleanup\nbyof.destroy()\n```\n\nThat's it! BYOF renders a chat UI and sandbox for generated apps.\n\n## How It Works\n\n```\nUser Input → BYOF → Your Backend → LLM → Generated HTML → Sandboxed Iframe\n```\n\n1. User describes what they want in the chat\n2. BYOF sends the request to your backend\n3. Your backend calls an LLM (Claude/GPT)\n4. LLM generates a single-file HTML app\n5. BYOF renders it in a secure sandboxed iframe\n\n## Configuration\n\n```typescript\nconst byof = createByof({\n  // Required\n  mount: document.getElementById('app')!,\n  chatEndpoint: '/api/chat',\n\n  // Optional: API specification (so generated UIs know your API)\n  apiSpec: '{ \"openapi\": \"3.0.0\", ... }', // or:\n  apiSpecUrl: '/api/openapi.json',\n\n  // Optional: Save/Load functionality\n  saveEndpoint: '/api/save',\n\n  // Optional: Context for multi-tenant apps\n  projectId: 'project-123',\n  userId: 'user-456',\n\n  // Optional: Security - allowed origins for generated app API calls\n  sandbox: {\n    allowlist: ['https://api.example.com', 'http://localhost:3001'],\n  },\n\n  // Optional: Auth headers for generated apps\n  getAuthHeaders: () => ({\n    Authorization: `Bearer ${localStorage.getItem('token')}`,\n  }),\n\n  // Optional: Theme customization\n  theme: {\n    primaryColor: '#6366f1',\n    backgroundColor: '#0f172a',\n    textColor: '#f8fafc',\n  },\n\n  // Callbacks\n  onHtmlGenerated: (html, title) => console.log('Generated:', title),\n  onError: (error) => console.error(error.code, error.message),\n  onSaveComplete: (ref) => console.log('Saved:', ref.id),\n  onLoadComplete: (ref) => console.log('Loaded:', ref.id),\n})\n```\n\n## Instance Methods\n\n```typescript\n// Update configuration\nbyof.setApiSpec(newSpec)\nbyof.setChatEndpoint('/api/v2/chat')\nbyof.setSaveEndpoint('/api/v2/save')\n\n// Save/Load\nconst ref = await byof.saveCurrent('My App')\nawait byof.loadSaved(ref.id)\n\n// Reset conversation\nbyof.reset()\n\n// Cleanup\nbyof.destroy()\n```\n\n## Backend Implementation\n\nBYOF sends requests to your backend endpoints. Here's what to implement:\n\n### Chat Endpoint\n\n```typescript\n// POST /api/chat\ninterface ChatRequest {\n  messages: Array<{ role: string; content: string }>\n  systemPrompt: string // Built by BYOF - pass to LLM as system message\n  apiSpec?: string // Your OpenAPI spec (also in systemPrompt)\n  context?: { projectId?: string; userId?: string }\n}\n\ninterface ChatResponse {\n  html: string // The generated single-file HTML app\n  title?: string // Optional title for the UI\n  warnings?: string[] // Optional warnings to log\n}\n```\n\nYour backend receives the `systemPrompt` from BYOF - just pass it to the LLM as the system message.\n\n### Save Endpoints (Optional)\n\n```typescript\n// POST /api/save - Save a generated UI\n// POST /api/save/load - Load by ID\n// POST /api/save/list - List saved UIs\n```\n\nSee `examples/backend/server.js` for a complete implementation.\n\n## Backend Types\n\nImport types for your backend:\n\n```typescript\nimport type {\n  ChatRequest,\n  ChatResponse,\n  SaveRequest,\n  SaveResponse,\n  LoadRequest,\n  LoadResponse,\n  ListRequest,\n  ListResponse,\n} from 'byof'\n```\n\n## Theming\n\nPass a theme object or use CSS variables:\n\n```typescript\n// Theme object\ncreateByof({\n  theme: {\n    primaryColor: '#6366f1',\n    backgroundColor: '#0f172a',\n    textColor: '#f8fafc',\n    borderColor: '#334155',\n    fontFamily: 'Inter, sans-serif',\n    borderRadius: '8px',\n  },\n})\n```\n\n```css\n/* Or CSS variables */\n.byof-container {\n  --byof-primary: #6366f1;\n  --byof-bg: #0f172a;\n  --byof-text: #f8fafc;\n  --byof-border: #334155;\n}\n```\n\n## Security\n\nBYOF takes security seriously:\n\n- **Sandboxed iframes** - Generated apps run in isolated iframes\n- **CSP protection** - Network calls restricted to your allowlist\n- **No localStorage** - Generated apps can't access parent storage\n- **Auth injection** - Securely pass auth headers to generated apps\n\n## Examples\n\nRun the included example:\n\n```bash\n# Install dependencies\nnpm install\n\n# Build library + run frontend + backend\nnpm run example\n```\n\nThen open http://localhost:3000\n\n## Development\n\n```bash\nnpm install          # Install dependencies\nnpm run build        # Build the library\nnpm run dev          # Watch mode\nnpm run test         # Run tests\nnpm run lint         # Lint code\nnpm run typecheck    # Type check\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}