This is a Next.js starter project featuring:
- Prisma: Prisma ORM is an open source Node.js and TypeScript ORM with a readable data model, automated migrations, type-safety, and auto-completion.
- Xata: Xata is a serverless data platform, built on PostgreSQL which provides a full-text and vector search engine, record-level file attachments, table-level aggregations and an optional ask endpoint to engage with with OpenAI's ChatGPT API.
- Clerk: Clerk is a User Management Platform, offering a complete suite of embeddable UIs, flexible APIs, and admin dashboards to authenticate and manage your users.
- Inngest: Inngest is an event-driven durable execution engine that enables you to run reliable code on any platform, including serverless.
How the app works:
- The app features a sign in/sign out functionality using Clerk and the avatar of the currently logged user is shown in the top-right corner
- User's messages are sent to/read from Xata using Prisma ORM
- Finally, an Inngest function is responsible for reliably generating an answer to the user's message using OpenAI
- Get started with Next.js and Xata
- Using Prisma with Xata's Postgres service
- Setting up your Clerk account
- Clerk Next.js Quick Start
- Inngest Quick Start
This boilerplate was created using create-next-app
, has Prisma already set up (see ./prisma
), as well as Inngest (see ./inngest
and ./api/inngest
).
While Inngest requires an account for production, using Inngest Dev Server for local development is free and doesn't require any setup.
The following steps will guide you through setting up your Xata and Clerk accounts.
npm install -g @xata.io/cli
xata auth login
Next:
- Choose Create new API key in the browser.
- Create account or sign in in the browser.
- Create a new API key.
- Go to the Xata dashboard. If you haven't previously created any Xata database, click "Skip connection guide" button.
- Go to your workspace settings.
- Select "Direct access to Postgres".
- Go to the Xata dashboard.
- Create a new database, choosing the Enable direct access to Postgres option.
- Once you've created the database, click the "Generate new API key" button in the database settings screen.
You will be now be able to see your Xata database connection string, with the pre-populated API key, which looks like this:
postgresql://<YOUR_WORKSPACE_ID>:<YOUR_API_KEY>@<YOUR_REGION>.sql.xata.sh:5432/<YOUR_DATABASE_NAME>:<YOUR_BRANCH_NAME>
Back in your code editor, in your project's root create a new file called .env
. Using the value from the previous step, add a new environment variable called DATABASE_URL
, like this:
DATABASE_URL=postgresql://...?sslmode=require
You can also see an example of the .env
file in ./.env.example
.
Migrations with Prisma require a shadow database. For this purpose, you'll need to create an additional database in Xata.
Repeat the previous step's instructions to create a new database. Name it something like <YOUR_APP_NAME>-migrations
.
This time you'll need to populate the API key in the connection string by hand. You can use the same API key as for the main database connection.
Once done, configure the database connection string in your .env
file as SHADOW_DATABASE_URL
:
SHADOW_DATABASE_URL=postgresql://...?sslmode=require
Run the initial Prisma migration to create the database schema.
npx prisma db push
Sign up or sign in to Clerk and create a new application.
Choose any login mechanisms you'd like to allow your users to sign in with. You can change these later.
Once the application is created, see the section called "Set your environment variables" and copy the generated environment variables and add them to your .env
file
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_abcdefghijklmnopqrstuvwxyz
CLERK_SECRET_KEY=••••••••••••••••••••••••••••••••••••••••••••••••••
You can skip the other suggested steps in the Clerk setup, they've already been included in this boilerplate.
You will use two Dev Servers.
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Open http://localhost:3000 with your browser to see your app.
npx inngest-cli dev
Open http://localhost:8288 with your browser to see the Inngest UI.
- Blog post: AI in production: Managing capacity with flow control
- Video: Automate All of Your Customer Emails with AI in Next.js
- Blog post: Semi-Autonomous AI Agents and Collaborative Multiplayer Asynchronous Workflows
- Docs: Inngest for AI
- Concurrency - Concurrency controls the number of steps executing code at any one time. It works by creating multi-level virtual queues within each function, directly in code, without thinking about infrastructure.
- Debouncing - Debounce delays function execution until a series of events are no longer received. This is useful for preventing wasted work when a function might be triggered in quick succession.
- Prioritization - Priority allows you to dynamically execute some runs ahead or behind others based on any data. This allows you to prioritize some jobs ahead of others without the need for a separate queue.
- Rate limiting - Rate limiting is a hard limit on how many function runs can start within a time period. Events that exceed the rate limit are skipped and do not trigger functions to start. This prevents excessive function runs over a given time period.
- Steps - Steps are fundamental building blocks in Inngest functions. Each step represents individual task (or other unit of work) within a function that can be executed independently.
- Throttling - Throttling allows you to specify how many function runs can start within a time period. When the limit is reached, new function runs over the throttling limit will be enqueued for the future.
- Docs: Prisma ORM