What is our tech stack

Reading time3min


Updated


Authors

Back-end

We use TypeScript and Node.js in all our back-end applications. Where possible, we run them in a serverless environment, this includes using Next.js API Routes on Vercel, AWS Lambda for background jobs, and AWS ECS Fargate for APIs.

To handle spikes in traffic and keep services separate, we use queues. This setup helps us scale parts of the system without affecting others. We limit the impact of failures by splitting responsibilities between a control plane and a data plane. The control plane handles requests, and the data plane sends emails.

We currently use Express for APIs. We are moving to Hono for its performance benefits and simplicity.

Front-end

We use React with Next.js for our dashboard and public website.

For styling we build custom components using Tailwind CSS, Radix Primitives, and Radix Colors.

Since Next.js 15, we primarily use React Server Components to fetch data, while still using SWR for routes that haven't been migrated yet. We also use Zod to parse requests and responses into strongly-typed schemas.

Auth

We use Supabase for authentication, which gives us the ability to manage multiple sign-in methods including email/password, and OAuth providers.

We built our own organization model on top of Supabase to allow users to be part of multiple teams.

Deployments

Our workloads are split between Vercel and AWS.

We choose the best provider for the job depending on the problem we're trying to solve. For example, using Vercel with Next.js allows us to ship features quickly using Preview Deployments.

Storage

We use Postgres as our main storage system, and the applications consume data using Drizzle as the ORM/query-builder.

For analytics purposes, we store data in Tinybird so we can get aggregate data for various use cases.

We also have Redis, used for caching data for fast access.

Observability

We use a combination of tools to monitor our applications:

Infrastructure

We use AWS CDK and Terraform for infrastructure management.

Our CI/CD pipelines are powered by GitHub Actions along with Buildjet as a runner.

Background jobs

We have many background jobs that are triggered from different flows; the goal is to make requests faster by moving non-critical code out of the main path or to perform an action continuously based on some criteria.

Our main tool is Inngest, which provides a great developer experience and helps us visualize and debug background jobs.

Documentation

Our documentation is written using Markdown and is powered by Mintlify, which lets us focus more on writing the best content we can.

Webhooks

We use Svix for processing webhooks to our users. It's a great tool that helps us monitor and scale webhooks with automatic retries.

Testing

We use Vitest as our testing framework for unit testing. We don't enforce a specific test coverage, and we try to be reasonable in balancing the amount of tests we write.

We don't have UI tests or E2E tests in our dashboard, but we know we need them sooner rather than later.

Miscellaneous

  • pnpm as a package manager
  • TypeScript is the default. We try to be very strict about its rules
  • Pino is our logger library across the board
  • MDX is how we write content
  • Biome for fast linting and formatting