A NextJS App Router project that follows the Replicache Demos: Todo Row Versioning, Introduction, and Build Your Own Back End.
Please refer to the main
branch for the Todo Row Versioning Demo, the turso-database
branch for Turso as the database driver, and build-your-own-backend
branch for the Introduction and Build Your Own Back End Demos.
-
Vanilla JavaScript → NextJS App Router with
use server
anduse client
components -
PandaCSS
-
Postgres → Drizzle + SQLite (better-sqlite3)
-
Pusher → Soketi
The significant feature of Next.js App Router is Server Components.
This allows more of your application to receive the benefits of server rendering.
PandaCSS is our preferred UI framework. It was launched by the Chakra UI team with the developer experience, semantics, and readability like with Chakra UI and zero runtime CSS-in-JS for Server Components compatibility like with TailwindCSS.
We use Drizzle as our ORM that is lightweight, performant, and SQL-like with our local database of choice: SQLite.
Once the database is initialized, you may use Drizzle Studio to see our tables.
First, run the command:
pnpm drizzle-kit studio
Which will run at a local address:
Drizzle Studio is up and running on https://0.0.0.0:xxxx
Open the URL in your browser to see our tables and data.
We use Soketi for our web socket service to send and receive pokes. When we push data, send a poke to notify all other applications to pull for the updated data. No data is actually sent with pokes.
While we use Soketi to host our websocket endpoint server we still use the Pusher SDK. However, our endpoint is now our self-hosted Soketi server instead of Pusher's priced and managed service server.
We need to use the Pusher JS library for instances and functions on the client side and the Pusher library (pusher-http-node) for instances and functions on the server side.
Note that the Pusher client instance parameters are slightly different between the client pusher-js
library and the server pusher
library.
We do not need a Pusher account or app.
We don't need soketi as a project dependency of our NextJS application but have access to running a Soketi server through their command line.
The fields of the app id, key, and cluster are required parameters but the values are insignificant and aren't used.
The important parameter values are port and host.
We use soketi start
to start our local Soketi server.
In production, we would continually run our soketi server in a container by way of command line or docker file in a virtual instance such as AWS EC2/ECS, Fly.io, or Digital Ocean.
Install the application dependencies:
pnpm install
Install the Soketi command line:
pnpm install -g @soketi/soketi
Then, run the local Soketi server:
soketi start
Run the command:
pnpm dlx replicache@latest get-license
Then, add your key to your .env.local
file.
REPLICACHE_LICENSE_KEY=your-license-key-here
Run the Drizzle push command:
pnpm push
Run the command:
pnpm dev
Ensure that the host and port is of the same in the Soketi server as the NextJS application.
Open https://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx
. The page auto-updates as you edit the file.
You may comment out the <IntroductionDemo/>
component or the <Chat/>
component to run the respective code for the Introduction Demo or the Bring Your Own Back End (Chat) Demo.
We use ESLint for our code style. You may modify the ESLint rule set in the .eslintrc.js
file. Include ESLint On Save in your code editor Preferences settings.
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
See
A quick look at the top-level files and directories where we made our feature changes in the project.
drizzle
├── db.ts
├── initializeDatabase.ts
└── schema.ts
recipes
└── table.recipe.ts
replicache
├── constructor.ts
├── license.ts
├── mutators.ts
└── types.d.ts
src
└── app
├── api
| ├── replicache-pull/route.ts
| └── replicache-push/route.ts
├── list
| └── [listIDSlug]
| └── page.tsx
├── actions
| └── replicache
| ├── appActions.ts
| ├── listenActions.ts
| ├── pokeActions.ts
| ├── pullActions.ts
| ├── pushActions.ts
| ├── sharedActions.ts
| └── todoActions.ts
├── layout.tsx
├── page.tsx
├── components
| ├── park-ui
| | ├── ...
| | └── ...
| ├── ...
| └── ...
└── lib
├── create-replicache-context.tsx
└── create-style-context.tsx
drizzle.config.ts
panda.config.ts
-
/drizzle
: This directory will contain the code related to setting up and calling our SQLite database with Drizzle. -
drizzle/db.ts
: This file contains our server ID and SQLite database object. -
db/initializeDatabase.ts
: This file initializes our database by insertingserver ID: 1
andversion: 1
into our replicacheServer table. -
drizzle/schema.ts
: This file contains our Drizzle schema that declares our table fields and the typescript type definitions of our tables. -
recipes/
: This directory will contain the recipe files for us to apply and override any new styles over our preset styles of our Ark UI / Park UI components -
recipes/table.recipe.ts
: This file contains the Table component styles to apply and override from the Park UI Panda Preset styes. -
/replicache
: This directory will contain the code related to Replicache. -
replicache/constructor.ts
: This file declares our Replicache objects. -
replicache/license.ts
: This file contains our tutorial license key. -
replicache/mutators.ts
: This file contains the CRUD functions that interact with our local IndexedDB in-browser database. -
replicache/types.d.ts
: This file contains our type definitions for our content data: Message and MessageWithID -
/src/app
: This directory will contain all of the code related to what you will see on the front-end of the site.src
is a convention for “source code” andapp
is the convention for “app router”. -
/src/app/api
: This directory will contain our API Route Handlers. -
/src/app/api/replicache-pull/route.ts
: This file is our API Route Handler that processes our Pulls. It returns an object of the list of getLastMutationIDChanges, the current version, and the list of put/delete operations to update to latest. -
/src/app/api/replicache-push/route.ts
: This file is our API Route Handler that processes our Pushes. It applies the latest mutations (messages submitted) and updates the latest version. It sends a poke to notify all other clients to pull for update changes. -
src/app/list/[listIDSlug]/page.tsx
: This file contains the code for the list pages at the/list/{listID}
page routes. See NextJS Documentation: Pages -
src/app/layout.tsx
: This file contains the Root Layout. The JSX elements in this file applies onto all routes with routes being{children}
. See NextJS Documentation: Layouts -
src/app/page.tsx
: This file contains the code for the home root front-end page. See NextJS Documentation: Pages -
src/app/actions/replicache
: This directory will contain all of our server action files related to Replicache. -
/appActions.ts
: This file contains the CRUD functions that interact with Drizzle and our remote SQLite database. -
/listenActions.ts
: This file contains the Pusher client-side helper function to listen for pokes. -
/pokeActions.ts
: This file contains the Pusher server-side helper function to send pokes. -
/pullActions.ts
: This file contains the process pull helper functions. -
/pushActions.ts
: This file contains the process push helper functions. -
/sharedActions.ts
: This file contains the helper functions that relate to Client Group that are both used by process pull and process push. -
/todoActions.ts
: This file contains the helper functions that wrap around the replicache mutators that are called by our Todo component. -
/components
: This directory will contain all of our front-end TSX components used in our Layout and Pages. -
/components/park-ui
: This directory will contain all of our Ark UI / Park UI components. See Ark UI Documentation and Park UI Documentation -
/lib
: This directory will contain our custom Context API hooks to pass down instances of values and objects across our components. -
/lib/create-replicache-context.tsx
: This file contains our Replicache Context that is used to pass down our replicache and userID instances across our page components. -
/lib/create-style-context.tsx
: This file contains our Style Context that is used to create our Ark UI / Park UI components. -
drizzle.config.ts
: This file configures Drizzle with the needed files and paths -
panda.config.ts
: This file configures Panda for our css, file system, and JSX options. See Panda Config Documentation
Thank you to Aaron Boodman, the Rocicorp team, and all the contributors for the creation of Replicache.