├── .gitignore ├── tsconfig.json ├── src ├── renderer.tsx ├── client.tsx └── index.tsx ├── wrangler.toml ├── vite.config.ts ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .wrangler 4 | .dev.vars 5 | 6 | # Change them to your taste: 7 | package-lock.json 8 | yarn.lock 9 | pnpm-lock.yaml 10 | bun.lockb -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "lib": [ 8 | "DOM", 9 | "ESNext" 10 | ], 11 | "types": [ 12 | "vite/client", 13 | "@cloudflare/workers-types" 14 | ], 15 | "jsx": "react-jsx", 16 | "jsxImportSource": "react" 17 | }, 18 | } -------------------------------------------------------------------------------- /src/renderer.tsx: -------------------------------------------------------------------------------- 1 | import { reactRenderer } from '@hono/react-renderer' 2 | 3 | export const renderer = reactRenderer(({ children }) => { 4 | return ( 5 | 6 |
7 | {import.meta.env.PROD ? ( 8 | 9 | ) : ( 10 | 11 | )} 12 | 13 | {children} 14 | 15 | ) 16 | }) 17 | -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "hono-with-vercel-ai" 2 | compatibility_date = "2024-01-01" 3 | pages_build_output_dir="./dist" 4 | 5 | # [vars] 6 | # MY_VAR = "my-variable" 7 | 8 | # [[kv_namespaces]] 9 | # binding = "MY_KV_NAMESPACE" 10 | # id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 11 | 12 | # [[r2_buckets]] 13 | # binding = "MY_BUCKET" 14 | # bucket_name = "my-bucket" 15 | 16 | # [[d1_databases]] 17 | # binding = "DB" 18 | # database_name = "my-database" 19 | # database_id = "" 20 | 21 | # [ai] 22 | # binding = "AI" -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import pages from '@hono/vite-cloudflare-pages' 2 | import devServer from '@hono/vite-dev-server' 3 | import { defineConfig } from 'vite' 4 | 5 | export default defineConfig(({ mode }) => { 6 | if (mode === 'client') { 7 | return { 8 | build: { 9 | rollupOptions: { 10 | input: './src/client.tsx', 11 | output: { 12 | entryFileNames: 'static/client.js' 13 | } 14 | } 15 | } 16 | } 17 | } else { 18 | return { 19 | ssr: { 20 | external: ['ai', '@ai-sdk/openai', 'react', 'react-dom'] 21 | }, 22 | plugins: [ 23 | pages(), 24 | devServer({ 25 | entry: 'src/index.tsx' 26 | }) 27 | ] 28 | } 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "dev": "vite", 5 | "build": "vite build --mode client && vite build", 6 | "preview": "wrangler pages dev dist", 7 | "deploy": "wrangler pages deploy dist" 8 | }, 9 | "dependencies": { 10 | "@ai-sdk/openai": "^0.0.56", 11 | "@hono/react-renderer": "^0.1.1", 12 | "@hono/zod-validator": "^0.2.1", 13 | "ai": "^3.0.18", 14 | "hono": "^4.2.2", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "zod": "^3.22.4" 18 | }, 19 | "devDependencies": { 20 | "@cloudflare/workers-types": "^4.20240403.0", 21 | "@hono/vite-cloudflare-pages": "^0.2.5", 22 | "@hono/vite-dev-server": "^0.10.0", 23 | "@types/react": "^18.2.74", 24 | "@types/react-dom": "^18.2.24", 25 | "vite": "^5.2.8", 26 | "wrangler": "^3.47.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # An example of using Vercel AI SDK with Hono 2 | 3 | This is a project to provide an example of using [Vercel AI SDK](https://sdk.vercel.ai/docs) with Hono. 4 | 5 | ## Features 6 | 7 | - Minimal. 8 | - Using React on both the server side and client side. 9 | - Validating incoming values with Zod. 10 | - Streaming Response. 11 | - Develop with Vite in local. Deploy to Cloudflare Pages. 12 | 13 | ## How to try 14 | 15 | Install: 16 | 17 | ```sh 18 | npm i 19 | ``` 20 | 21 | Develop: 22 | 23 | ```sh 24 | export OPENAI_API_KEY=your-openai-api-key 25 | npm run dev 26 | ``` 27 | 28 | Deploy to Cloudflare Pages: 29 | 30 | ```sh 31 | npm run deploy 32 | ``` 33 | 34 | Note: For production usage, you should add an environment value for `OPENAI_API_KEY` in your Cloudflare Dashboard. 35 | 36 | ## Author 37 | 38 | Yusuke Wada 39 | 40 | ## License 41 | 42 | MIT 43 | -------------------------------------------------------------------------------- /src/client.tsx: -------------------------------------------------------------------------------- 1 | import { useChat } from 'ai/react' 2 | import { createRoot } from 'react-dom/client' 3 | 4 | function Chat() { 5 | const { messages, input, handleInputChange, handleSubmit } = useChat() 6 | return ( 7 |