In this post, I'll introduce you to the TERN stack, explain why you should consider adopting it or migrating your MERN stack application over to TERN, and show how you can get started using hot-off-a-git-push 🔥 TERN GitHub template.
The TERN stack is an evolution of the MERN stack, replacing MongoDB with Tigris.
The TERN stack is made up of:
- Tigris: An open source Serverless NoSQL Database & Search platform
- Express.js: Fast, unopinionated, minimalist web framework for Node.js
- React: The library for web and native user interfaces
There is a proliferation of new fullstack all-in-one frameworks such as Next.js, Nuxt.js, SvelteKit, Redwood.js, Blitz.js, Astro, Gatsby... However, there is still some value in choosing to go with a more loosely coupled architecture:
• Better flexibility, maintainability, and scalability: components can be added, removed, or modified with minimal impact on other parts of the system.
• Increased reusability: System components can be reused across different systems or applications, reducing the time and effort required to develop new systems.
• Better fault tolerance: If one component fails, it is less likely to affect the entire system. The system can continue to operate with minimal disruption while the failed component is replaced or repaired.
• Simplified testing: It is easier to isolate and test individual parts of the system.
• Reduced dependencies: Fewer dependencies between components, which can reduce the complexity and cost of development and maintenance. And dependency hell.
• Improved performance: In some cases, loosely coupled architectures can improve performance by allowing components to operate independently and in parallel.
And you get this by building a loosely coupled front-end and back-end with the TERN stack.
The T in TERN stands for Tigris, an open source NoSQL database and search platform. So, the benefits that Tigris offers are also direct benefits in TERN:
- Takes a code-first approach to database schema modeling and search index modeling.
- Supports database branching to fit into your development workflow.
- Supports ACID transactions without caveats.
- Is a unified developer data platform offering Database AND Search in the same platform. There's no requirement to run a database and search service in parallel.
- Has been built with a modern cloud-native architecture, meaning the running costs are lower than MongoDB, DynamoDB etc.
- Tigris Cloud is fully managed, removing any need for manual cluster provisioning and shard management that are apparent in solutions such as MongoDB Atlas.
A computer, Git and Node.js installed on it, 10 minutes of your time... That's about it!
You can scaffold out your own TERN stack application using your favorite combination of CRA (Create React App), Vite templates, Express.js app generator etc. etc.
However, I want you to be able to get hands-on and building as quickly as possible. So, I created a TERN stack GitHub template. The TERN stack template is made up of:
- A client created using the Vite React TypeScript template
- An Express.js server carefully hand-crafted by yours truly. In TypeScript!
- A shared package so that client and server can benefit from a shared interface definition for client-server communication. TypeScript.
- All this packaged up in a monorepo (sounds way more monolithic than it is; it's just three packages using NPM workspaces). Not TypeScript 😞
So, let's get started.
Head to the TERN stack GitHub template and either Use this template -> Create a new repository -> Choose a name for your repo e.g.
tern-app -> and Clone your repo locally.
Now that you have the code cloned locally (on that computer I flagged as being important earlier),
cd into the application directory and install the dependencies for the monorepo/workspace.
cd tern-app npm i -ws --include-workspace-root
This installs the dependencies for React application, Express.js application, shared package, and the root workspace (the top-level
The TERN stack template provides a command to create a Tigris project from the command line. It makes use of the Tigris CLI and will take you through the flow of authorizing itself with Tigris Cloud. This means either logging into your existing Tigris Cloud account or creating a new account.
Run the following NPM script:
npm run tigris:init --project=tern-app
Once you have authorized the Tigris CLI it will create a new
.env.local file in
apps/server, containing Tigris project configuration. This will be loaded into the Express.js app and used with the Tigris TypeScript SDK.
Start the React client using the following command:
npm run dev -w=@tern-app/client
And start the Express.js server with the following command:
npm run dev -w=@tern-app/server
You can now launch your browser and head to
http://localhost:3000 to see your TERN app in action.
Clicking in the page will add rotating stars to the UI, their location is persisted in an
events collection within Tigris Database via the Express.js server. Clicking on an existing star removes it, and the details of that event are removed from the Tigris Database
. ├── apps │ ├── client │ │ ├── index.html │ │ └── src │ │ ├── App.css │ │ ├── App.tsx │ │ ├── index.css │ │ ├── lib │ │ │ └── analytics.ts │ │ └── main.tsx │ │ │ └── server │ ├── scripts │ │ └── setup.ts │ ├── src │ │ ├── db │ │ │ └── models │ │ │ └── event.ts │ │ │ │ │ ├── index.ts │ │ └── utils │ │ └── validateInput.ts │ └── .env.local └── packages └── shared └── src ├── event.ts └── index.ts
The React application, powered by Vite. The main files in this template are:
src/App.tsx: contains the UI-related functionality. In the default template example, this file manages tracking clicks and displaying clicks. It uses
src/lib/analytics.tsto interact with the Express.js server API endpoints.
src/lib/analytics.tsprovides a simple wrapper around
fetchrequests made to API endpoints defined by the Express.js server.
The Express.js application.
script/setup.ts: A file that is run before most other scripts to ensure the Tigris data models defined in TypeScript are in sync with that is in Tigris.
src/db/models/event.ts: Defines the Tigris data models that represent the application's database schema.
src/index.ts: The main entry point for the Express.js application. Defines the API endpoints and makes use of the Tigris TypeScript SDK to insert and delete documents into the NoSQL database.
src/utils/validateInput.ts: an Express.js middleware wrapper that makes use of zod to validate request body payloads to the API endpoints.
.env.local: Contains environmental variables used within the application. This was created via the
tigris:initscript and contains the Tigris project configuration.
src/event.ts: Defines interfaces that are used both within the client and server. This is a great step towards ensuring that the loose coupling between client and server doesn't also result in API requests and responses mismatching. I personally think this is a really powerful. It's also great for refactoring code between the client and server.
Dive into the codebase, make updates, and find out more.
This is v0.1.0 of the TERN stack template, and there are a few known issues if you'd like to help out.
Give me (@leggetter) a shout on Twitter.
Join the Tigris Discord to share your feedback, get help, or generally hang out.