{"_id":"awaitio","_rev":"6-0c1d7bb6e1aa2007b8b854aa53be225a","name":"awaitio","dist-tags":{"latest":"1.2.0"},"versions":{"0.0.0-stage":{"name":"awaitio","version":"0.0.0-stage","_id":"awaitio@0.0.0-stage","stub":true,"maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"dist":{"shasum":"e2cda31b2ee534d5db447f3a2186da6a1f416c29","tarball":"https://registry.npmjs.org/awaitio/-/awaitio-0.0.0-stage.tgz","fileCount":2,"integrity":"sha512-f8h5GG2YoZF9PORTCr1BW2aNtuyYcZgaxTr9tOczD5PUZUbdzFu/H6O/PNJpk0Lu4OyeULd1XlvLiYqiIxm4iA==","signatures":[{"sig":"MEUCIQC8DzmheAKVyw/cSPLwfMM2r1X57sCvtVWh2/tSejhFyAIgChApev0a5QYZIJjxc0dmpwE69y3c17C2fShcwneED2w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":329},"_npmUser":{"name":"homoky","email":"p.homoky@gmail.com"},"description":"Temporary package placeholder for staged publishing","directories":{}},"0.0.1":{"name":"awaitio","version":"0.0.1","license":"SEE LICENSE IN LICENSE","_id":"awaitio@0.0.1","maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"dist":{"shasum":"80d0df1fbe48a596e3e5a273e704dc11fb416bf7","tarball":"https://registry.npmjs.org/awaitio/-/awaitio-0.0.1.tgz","fileCount":668,"integrity":"sha512-KvGFrl+N1OOsi2mGreIQZWLBa/KLENAS6eBFLvXbS4fMzknNBiuL/lzVuN1ln0XU5GgLOr4Hna9H00aafb52cQ==","signatures":[{"sig":"MEQCIHNV5dGnzWC2I5IM6GOAGzC9mC63l2YHaVphWR4WF37YAiBSscnxIHmWCoeSoP+qCnuZngcjivoWIhR9DU7puWF/Tg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIEh91jd+f0Ln3zqdc97D/xGsGP0RnWcPy07WRup2szcjAiAHn4V2CcnLMhZP5L5g7vqGZAauAccblqONTUaUWGRosA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":755293},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./ui":{"types":"./dist/uikit/index.d.ts","default":"./dist/uikit/index.js"},"./vite":"./vite/componentBuildConfig.mjs","./client":{"types":"./dist/esm/client/index.d.ts","default":"./dist/esm/client/index.js"}},"gitHead":"34b764b0ad9b06843e3429cae0afe55ed1c77cc2","scripts":{"dev":"tsc -p tsconfig.client.json --watch --preserveWatchOutput & tsc -p tsconfig.build.json --watch --preserveWatchOutput","tsc":"tsc --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.ui.json","lint":"eslint .","test":"vitest run","build":"rm -rf dist && tsc -p tsconfig.build.json && tsc -p tsconfig.client.json && vite build","dev:ui":"vite","lint:fix":"eslint . --fix"},"_npmUser":{"name":"homoky","email":"p.homoky@gmail.com"},"_npmVersion":"10.9.2","description":"Internal tools in one process: actions in code await a human's answer, the same server serves the UI.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"zod":"3.22.4","luxon":"^3.7.2","react":"^19.1.0","express":"^4.21.2","ts-pattern":"^5.9.0"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.1.0","geist":"1.4.2","vitest":"^3.2.0","react-dom":"^19.1.0","typescript":"npm:@typescript/typescript6@^6.0.2","@types/node":"^22.14.0","tailwindcss":"^4.1.0","@types/luxon":"^3.7.1","@types/react":"^19.1.0","@types/express":"^4.17.21","@types/react-dom":"^19.1.0","@tailwindcss/vite":"^4.1.0","@typescript/native":"npm:typescript@^7.0.2","@vitejs/plugin-react":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/awaitio_0.0.1_1792457268310_0.6984851844556781","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"awaitio","version":"0.1.0","license":"SEE LICENSE IN LICENSE","_id":"awaitio@0.1.0","maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"dist":{"shasum":"75fc900c425db33c58223e1d894beef136147637","tarball":"https://registry.npmjs.org/awaitio/-/awaitio-0.1.0.tgz","fileCount":843,"integrity":"sha512-UJKoL5kwTSE0ny/xoxOUXWHhtNa8TQ6w89zS9r/wqT0ud/qtVU/ypoXovGBNHslQgae3keKi2yBOObd5dV25AQ==","signatures":[{"sig":"MEUCIQC1RT61bnIHGE5fqFY2C4GFayV8cm4ug7QAqPmdJkoldgIgf1KyNN96uN85/aQSOH8mHIuij2tpehao6kKY5IYVMko=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIDZvFbTy2sa/ZWN7Ja6oCjO3Afuyzpj4IwfPOGzjHxNjAiAs+4eSulfDQzFt1Sb1jETZYmlrNfMFIE+Fxy5ftzf5Wg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1057850},"main":"dist/index.js","_from":"file:awaitio-0.1.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./ui":{"types":"./dist/uikit/index.d.ts","default":"./dist/uikit/index.js"},"./vite":"./vite/componentBuildConfig.mjs","./client":{"types":"./dist/esm/client/index.d.ts","default":"./dist/esm/client/index.js"},"./package.json":"./package.json"},"scripts":{"dev":"tsc -p tsconfig.client.json --watch --preserveWatchOutput & tsc -p tsconfig.build.json --watch --preserveWatchOutput","tsc":"tsc --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.ui.json","lint":"eslint .","test":"vitest run","build":"rm -rf dist && tsc -p tsconfig.build.json && tsc -p tsconfig.client.json && vite build","dev:ui":"vite","release":"pnpm build && pnpm publish --access public --no-git-checks","lint:fix":"eslint . --fix"},"_npmUser":{"name":"homoky","email":"p.homoky@gmail.com"},"_resolved":"/private/var/folders/bp/_6q9k1c931qdxpx9zndhs4440000gn/T/494d1ad831c7904ccd0a96947c7ecad4/awaitio-0.1.0.tgz","_integrity":"sha512-UJKoL5kwTSE0ny/xoxOUXWHhtNa8TQ6w89zS9r/wqT0ud/qtVU/ypoXovGBNHslQgae3keKi2yBOObd5dV25AQ==","_npmVersion":"10.9.2","description":"Internal tools in one process: actions in code await a human's answer, the same server serves the UI.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"luxon":"^3.7.2","react":"^19.1.0","express":"^4.21.2","ts-pattern":"^5.9.0"},"typesVersions":{"*":{"ui":["./dist/uikit/index.d.ts"],"client":["./dist/esm/client/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","vite":"^7.1.0","geist":"1.4.2","vitest":"^3.2.0","react-dom":"^19.1.0","typescript":"npm:@typescript/typescript6@^6.0.2","@types/node":"^22.14.0","tailwindcss":"^4.1.0","@types/luxon":"^3.7.1","@types/react":"^19.1.0","@types/express":"^4.17.21","@types/react-dom":"^19.1.0","@tailwindcss/vite":"^4.1.0","@typescript/native":"npm:typescript@^7.0.2","@vitejs/plugin-react":"^5.0.0"},"peerDependencies":{"zod":"^3.25.0 || ^4.0.0","@types/react":"^19.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/awaitio_0.1.0_1792578792712_0.004845367922054367","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"awaitio","version":"1.0.0","license":"SEE LICENSE IN LICENSE","_id":"awaitio@1.0.0","maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"dist":{"shasum":"7ace2456e767d964a9a0490c2bc117f312a4c881","tarball":"https://registry.npmjs.org/awaitio/-/awaitio-1.0.0.tgz","fileCount":843,"integrity":"sha512-IMqCXrgdvAzlLVWPaxBxPtLIRawXHG3hHju8rVU7ioMJ9GOaRhNUHyCIHK8RJhMJUGWioVdfU5YjvNlD/6wiqg==","signatures":[{"sig":"MEUCIHw4CPhTubzzLJSjpcOp+nLvT/NZ/2dyd/yyJKKFGLwGAiEAz6sRTcuK5wKdflkCK4WeEDiGPI3MMlLIfSsy4cqQgRw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQC9zqocboN+c1fBcYEhsFp0aMeemLSgwlrknxxeJJ18nwIgfc4QJe/DON2KmBei3PKQOBBW+igEeeGeAQoYMHQbyts=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1065911},"main":"dist/index.js","_from":"file:awaitio-1.0.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./ui":{"types":"./dist/uikit/index.d.ts","default":"./dist/uikit/index.js"},"./vite":"./vite/componentBuildConfig.mjs","./client":{"types":"./dist/esm/client/index.d.ts","default":"./dist/esm/client/index.js"},"./package.json":"./package.json"},"scripts":{"dev":"tsc -p tsconfig.client.json --watch --preserveWatchOutput & tsc -p tsconfig.build.json --watch --preserveWatchOutput","tsc":"tsc --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.ui.json","lint":"eslint .","test":"vitest run","build":"rm -rf dist && tsc -p tsconfig.build.json && tsc -p tsconfig.client.json && vite build","dev:ui":"vite","release":"pnpm build && pnpm publish --access public --no-git-checks","lint:fix":"eslint . --fix"},"_npmUser":{"name":"homoky","email":"p.homoky@gmail.com"},"_resolved":"/private/var/folders/bp/_6q9k1c931qdxpx9zndhs4440000gn/T/a8b2229f455f0f2b8e5497d7b414b50b/awaitio-1.0.0.tgz","_integrity":"sha512-IMqCXrgdvAzlLVWPaxBxPtLIRawXHG3hHju8rVU7ioMJ9GOaRhNUHyCIHK8RJhMJUGWioVdfU5YjvNlD/6wiqg==","_npmVersion":"10.9.2","description":"Internal tools in one process: actions in code await a human's answer, the same server serves the UI.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"luxon":"^3.7.2","react":"^19.1.0","express":"^4.21.2","ts-pattern":"^5.9.0"},"typesVersions":{"*":{"ui":["./dist/uikit/index.d.ts"],"client":["./dist/esm/client/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","vite":"^7.1.0","geist":"1.4.2","vitest":"^3.2.0","react-dom":"^19.1.0","typescript":"npm:@typescript/typescript6@^6.0.2","@types/node":"^22.14.0","tailwindcss":"^4.1.0","@types/luxon":"^3.7.1","@types/react":"^19.1.0","@types/express":"^4.17.21","@types/react-dom":"^19.1.0","@tailwindcss/vite":"^4.1.0","@typescript/native":"npm:typescript@^7.0.2","@vitejs/plugin-react":"^5.0.0"},"peerDependencies":{"zod":"^3.25.0 || ^4.0.0","@types/react":"^19.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/awaitio_1.0.0_1792608235322_0.7063792711458425","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"awaitio","version":"1.1.0","license":"SEE LICENSE IN LICENSE","_id":"awaitio@1.1.0","maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"dist":{"shasum":"859ad432ba07c109b5a638c7b6327782caf5ede8","tarball":"https://registry.npmjs.org/awaitio/-/awaitio-1.1.0.tgz","fileCount":849,"integrity":"sha512-Lw0cFeiuG3JA1acd/jbgPEfiI1LJixDUFTKc44edalZwr9TkP7joy/7ZtfrLTr3OEku0oqFbAq+3XVOmH5nA+w==","signatures":[{"sig":"MEUCIQCe2u9dcfZN+700rlXA3fPDyOLac81BkeOYU7ahncUenAIgXisEeaXbBwfN3qNOEiQInfRoRo4hnyBQSY1ihZD9VSM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDUyKRY8VoRWkMqf+XgJ/gT+HBeFoAAsM+FNC9DfKkYNwIhAPEE7wsjqC+1Omb9E1wy8kLeg+zTjgMLC9kzjfm7KqE3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1075883},"main":"dist/index.js","_from":"file:awaitio-1.1.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./ui":{"types":"./dist/uikit/index.d.ts","default":"./dist/uikit/index.js"},"./vite":"./vite/componentBuildConfig.mjs","./client":{"types":"./dist/esm/client/index.d.ts","default":"./dist/esm/client/index.js"},"./package.json":"./package.json"},"scripts":{"dev":"tsc -p tsconfig.client.json --watch --preserveWatchOutput & tsc -p tsconfig.build.json --watch --preserveWatchOutput","tsc":"tsc --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.ui.json","lint":"eslint .","test":"vitest run","build":"rm -rf dist && tsc -p tsconfig.build.json && tsc -p tsconfig.client.json && vite build","dev:ui":"vite","release":"pnpm build && pnpm publish --access public --no-git-checks","lint:fix":"eslint . --fix"},"_npmUser":{"name":"homoky","email":"p.homoky@gmail.com"},"_resolved":"/private/var/folders/bp/_6q9k1c931qdxpx9zndhs4440000gn/T/6ae06f0b37272b6abf5fa2deb60d090f/awaitio-1.1.0.tgz","_integrity":"sha512-Lw0cFeiuG3JA1acd/jbgPEfiI1LJixDUFTKc44edalZwr9TkP7joy/7ZtfrLTr3OEku0oqFbAq+3XVOmH5nA+w==","_npmVersion":"10.9.2","description":"Internal tools in one process: actions in code await a human's answer, the same server serves the UI.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"luxon":"^3.7.2","react":"^19.1.0","express":"^4.21.2","ts-pattern":"^5.9.0"},"typesVersions":{"*":{"ui":["./dist/uikit/index.d.ts"],"client":["./dist/esm/client/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","vite":"^7.1.0","geist":"1.4.2","vitest":"^3.2.0","react-dom":"^19.1.0","typescript":"npm:@typescript/typescript6@^6.0.2","@types/node":"^22.14.0","tailwindcss":"^4.1.0","@types/luxon":"^3.7.1","@types/react":"^19.1.0","@types/express":"^4.17.21","@types/react-dom":"^19.1.0","@tailwindcss/vite":"^4.1.0","@typescript/native":"npm:typescript@^7.0.2","@vitejs/plugin-react":"^5.0.0"},"peerDependencies":{"zod":"^3.25.0 || ^4.0.0","@types/react":"^19.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/awaitio_1.1.0_1792664287853_0.1606840693935434","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"_id":"awaitio@1.2.0","dist":{"shasum":"f830901f3dd6c4eb59e6999b51c8346cda6bdfa2","tarball":"https://registry.npmjs.org/awaitio/-/awaitio-1.2.0.tgz","fileCount":849,"integrity":"sha512-1d1uBvccSTuS/poEqPNv5njYaFaRcjpoxiA47zUimLq+QtRbU5KAPor8Ye/uLPrH1pV9I6cxJsO6rweD5eTcVA==","signatures":[{"sig":"MEYCIQDzEq6CDAsrLzQGVx/RzZcjXUEAsPX9vFI5wNiy4m3rSgIhALDwuVI8o2D2+NWfIbbg0Wk328W4ZDs+1hR851JJRf02","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCEh7Qh4OHL8rcaZaGHHvJeref3Nzz0O2hsqsuazc0XVwIgV6itZraJcmEWxBFghrmqk8DkUfMxTt0QuJkK9+rJDys="}],"unpackedSize":1076499},"main":"dist/index.js","name":"awaitio","_from":"file:awaitio-1.2.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./ui":{"types":"./dist/uikit/index.d.ts","default":"./dist/uikit/index.js"},"./vite":"./vite/componentBuildConfig.mjs","./client":{"types":"./dist/esm/client/index.d.ts","default":"./dist/esm/client/index.js"},"./package.json":"./package.json"},"license":"SEE LICENSE IN LICENSE","scripts":{"dev":"tsc -p tsconfig.client.json --watch --preserveWatchOutput & tsc -p tsconfig.build.json --watch --preserveWatchOutput","tsc":"tsc --noEmit && tsc -p tsconfig.client.json --noEmit && tsc -p tsconfig.ui.json","lint":"eslint .","test":"vitest run","build":"rm -rf dist && tsc -p tsconfig.build.json && tsc -p tsconfig.client.json && vite build","dev:ui":"vite","release":"pnpm build && pnpm publish --access public --no-git-checks","lint:fix":"eslint . --fix"},"version":"1.2.0","_npmUser":{"name":"homoky","email":"p.homoky@gmail.com"},"_resolved":"/private/var/folders/bp/_6q9k1c931qdxpx9zndhs4440000gn/T/86ef485a6d71f27e6bc9df9f63dcb1c3/awaitio-1.2.0.tgz","_integrity":"sha512-1d1uBvccSTuS/poEqPNv5njYaFaRcjpoxiA47zUimLq+QtRbU5KAPor8Ye/uLPrH1pV9I6cxJsO6rweD5eTcVA==","_npmVersion":"10.9.2","description":"Internal tools in one process: actions in code await a human's answer, the same server serves the UI.","directories":{},"maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"_nodeVersion":"22.14.0","dependencies":{"luxon":"^3.7.2","react":"^19.1.0","express":"^4.21.2","ts-pattern":"^5.9.0"},"typesVersions":{"*":{"ui":["./dist/uikit/index.d.ts"],"client":["./dist/esm/client/index.d.ts"]}},"_hasShrinkwrap":false,"devDependencies":{"zod":"^4.3.6","vite":"^7.1.0","geist":"1.4.2","vitest":"^3.2.0","react-dom":"^19.1.0","typescript":"npm:@typescript/typescript6@^6.0.2","@types/node":"^22.14.0","tailwindcss":"^4.1.0","@types/luxon":"^3.7.1","@types/react":"^19.1.0","@types/express":"^4.17.21","@types/react-dom":"^19.1.0","@tailwindcss/vite":"^4.1.0","@typescript/native":"npm:typescript@^7.0.2","@vitejs/plugin-react":"^5.0.0"},"peerDependencies":{"zod":"^3.25.0 || ^4.0.0","@types/react":"^19.0.0"},"peerDependenciesMeta":{"@types/react":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/awaitio_1.2.0_1793089701164_0.5424186688313534"}}},"time":{"created":"2026-10-20T00:46:30.577Z","modified":"2026-10-27T08:28:21.556Z","0.0.0-stage":"2026-10-20T00:46:30.577Z","0.0.1":"2026-10-20T00:47:48.423Z","0.1.0":"2026-10-21T10:33:12.826Z","1.0.0":"2026-10-21T18:43:55.449Z","1.1.0":"2026-10-22T10:18:07.954Z","1.2.0":"2026-10-27T08:28:21.331Z"},"license":"SEE LICENSE IN LICENSE","description":"Internal tools in one process: actions in code await a human's answer, the same server serves the UI.","maintainers":[{"name":"homoky","email":"p.homoky@gmail.com"}],"readme":"# AwaitIO\n\nInternal tools in one Node process. Write each tool as an async TypeScript function; every `await` on `io` asks a person something in the browser and waits for the answer. The same server serves the UI, so there is nothing else to host.\n\n```ts\nexport const refundOrderAction = app.defineAction({\n  name: 'Refund order',\n  handler: async ({ io, ctx }) => {\n    const orderId = await io.input.text('Order ID');\n    const order = await prisma.order.findUniqueOrThrow({ where: { id: orderId } });\n    const reason = await io.input.textarea(`Why refund ${formatMoney(order.total)}?`);\n\n    await prisma.refund.create({ data: { orderId, reason, approvedBy: ctx.user.email } });\n\n    return { refunded: formatMoney(order.total) };\n  },\n});\n```\n\n<img src=\"https://docs.awaitio.com/images/intro-form.png\" alt=\"The Create account action: store and owner fields filled in for Juniper Tea, with a Continue button\" width=\"720\" />\n\n## Why AwaitIO\n\n- **One process.** The actions, the server and the UI run inside your own app. No hosted service, no second server, no database of its own.\n- **Your codebase.** A handler is a plain function: use your Prisma client, services, utilities and environment variables as they are.\n- **Typed end to end.** `io` is typed from the components you register; each component checks its props and its answer with zod on the server.\n- **Extensible.** A component is plain React in one file. Write your own and register it next to the built-in ones.\n- **Deploys with your app.** Each environment (production, staging, local) is its own server with its own secrets; the header switches between them.\n- **Private by default.** Login with email and password (scrypt hashes, signed cookies), runs visible only to the person who started them, the server listens on `127.0.0.1` unless you say otherwise.\n\n## Quickstart\n\n```bash\nnpm install awaitio @awaitio/theme-default @awaitio/input-text zod\n```\n\n```ts\n// app.ts\nimport { inputText } from '@awaitio/input-text';\nimport { defaultTheme } from '@awaitio/theme-default';\nimport { AwaitIO } from 'awaitio';\nimport { join } from 'path';\n\nexport const app = new AwaitIO({\n  name: 'Internal tools',\n  actionsDirectory: join(__dirname, 'actions'), // every file in it is an action, its path is the URL (/actions/greet)\n  theme: defaultTheme,\n  secret: process.env.SESSION_SECRET!,\n  users: [{ email: 'you@example.com', name: 'You', passwordHash: 'scrypt$…' }], // from Create new account on the login page\n  components: { input: { text: inputText } },\n});\n\n// actions/greetAction.ts\nexport const greetAction = app.defineAction({\n  name: 'Greet',\n  handler: async ({ io }) => {\n    const name = await io.input.text('Your name');\n\n    return `Hello, ${name}!`;\n  },\n});\n\n// server.ts\nvoid app.listen({ port: 3000 });\n```\n\nOpen http://localhost:3000, log in and run **Greet**.\n\n## Packages\n\n| Package                                                                             | What it is                                                                        |\n| ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |\n| [`awaitio`](https://docs.awaitio.com/core/app)                                      | The server, the action runtime, the prebuilt UI and `defineComponent`             |\n| [`@awaitio/theme-default`](https://docs.awaitio.com/core/theme)                     | The default look: every building block of `awaitio/ui`, with its styles           |\n| [`@awaitio/input-text`](https://docs.awaitio.com/io/input-text)                     | `io.input.text()`: one line of text                                               |\n| [`@awaitio/input-email`](https://docs.awaitio.com/io/input-email)                   | `io.input.email()`: an email address                                              |\n| [`@awaitio/input-url`](https://docs.awaitio.com/io/input-url)                       | `io.input.url()`: a web address, returned as a `URL`                              |\n| [`@awaitio/input-textarea`](https://docs.awaitio.com/io/input-textarea)             | `io.input.textarea()`: longer text                                                |\n| [`@awaitio/input-number`](https://docs.awaitio.com/io/input-number)                 | `io.input.number()`: a number, with min, max and decimal places                   |\n| [`@awaitio/input-boolean`](https://docs.awaitio.com/io/input-boolean)               | `io.input.boolean()`: yes or no, with a checkbox                                  |\n| [`@awaitio/input-datetime`](https://docs.awaitio.com/io/input-datetime)             | `io.input.datetime()`: a date and time, returned as a luxon `DateTime`            |\n| [`@awaitio/input-date`](https://docs.awaitio.com/io/input-date)                     | `io.input.date()`: a date, returned as a luxon `DateTime`                         |\n| [`@awaitio/select-single`](https://docs.awaitio.com/io/select-single)               | `io.select.single()`: one of a list of options                                    |\n| [`@awaitio/select-single-native`](https://docs.awaitio.com/io/select-single-native) | `io.select.singleNative()`: one of a list of options, in a native drop-down       |\n| [`@awaitio/select-multiple`](https://docs.awaitio.com/io/select-multiple)           | `io.select.multiple()`: any number of options                                     |\n| [`@awaitio/select-table`](https://docs.awaitio.com/io/select-table)                 | `io.select.table()`: rows picked from a table                                     |\n| [`@awaitio/confirm`](https://docs.awaitio.com/io/confirm)                           | `io.confirm()`: Confirm or Cancel before something irreversible                   |\n| [`@awaitio/display-table`](https://docs.awaitio.com/io/display-table)               | `io.display.table()` in pages: rows with filter, paging, links and row menus      |\n| [`@awaitio/display-metadata`](https://docs.awaitio.com/io/display-metadata)         | `io.display.metadata()` in pages: label and value tiles                           |\n| [`@awaitio/display-link`](https://docs.awaitio.com/io/display-link)                 | `io.display.link()`: a link to a page in the app or outside it                    |\n| [`@awaitio/display-heading`](https://docs.awaitio.com/io/display-heading)           | `io.display.heading()`: a section title with an optional description              |\n| [`@awaitio/display-image`](https://docs.awaitio.com/io/display-image)               | `io.display.image()`: a picture, such as a chart or a file preview                |\n| [`@awaitio/display-markdown`](https://docs.awaitio.com/io/display-markdown)         | `io.display.markdown()`: formatted text written in markdown                       |\n| [`@awaitio/display-object`](https://docs.awaitio.com/io/display-object)             | `io.display.object()`: the keys and values of a record, nested data included      |\n| [`@awaitio/display-html`](https://docs.awaitio.com/io/display-html)                 | `io.display.html()`: HTML markup, sanitized first                                 |\n| [`@awaitio/layout-basic`](https://docs.awaitio.com/io/layout-basic)                 | `io.layout.basic()`: the frame of a page, with its title, description and buttons |\n\n## Documentation\n\nThe documentation is at **[docs.awaitio.com](https://docs.awaitio.com)** – introduction, quickstart, how it works and security, every setting, routing, pages and layouts, themes, every `io` method and `ctx` field, custom components and deployment.\n\n## License\n\nAwaitIO is source-available under the AwaitIO License, the `LICENSE` file in this package. It is free, including commercial use, for up to 3 users and for non-profits and education. Larger teams pay one flat monthly price. Prices, examples and how to get a license are on [awaitio.com/pricing](https://awaitio.com/pricing).\n\n## Inspiration\n\nI'm Petr Homoky ([homoky.cz](https://homoky.cz)), the author of AwaitIO. Before I started on it, I built internal tools with [Interval](https://github.com/interval), and the idea behind it won me over: a tool is just backend code, and every `await` asks a person in the browser. AwaitIO keeps that idea and puts the actions, the server and the UI into one process inside your own app, so there is nothing else to run.\n","readmeFilename":"README.md"}