Skip to content

antoni-ostrowski/BETC-stack

Repository files navigation

My React web stack (BETC Stack Template)

I was tired of configuring tech stack every time I wanted to start new web app so i created this repo. This is exactly how I would start new web app today.

This repo is meant to be cloned and used as a starting point for a your next web app.

Getting Started

You can wire everything up yourself if you like, but I propose you just clone this repo to have my exact setup.

Remember to delete the .git folder, and init a new repo after cloning :)

git clone https://github.com/antoni-ostrowski/BETC-stack.git
cd BETC-stack
bun install
bun run dev
bunx convex dev

To make auth work, you need to have convex project, generate better-auth secret and generate schema (docs)

Technologies

These technologies create in my opinion the best web stack for complex web apps. Everything is fully typesafe and DX is next level.

Tooling

Styles

Some of the features in this template

  • Full authentication setup with Better-Auth + Convex adapter (Its a more flexible, "local install" version, which should enable better plugin support docs)
    • Example of protected route
    • Github sign in
    • handy hooks to access user data
  • Simple repository pattern implemented with EffectTS for data access layer (abstracted away from convex functions) with todo example
    • Utlity function to exec effect and wrap errors to ConvexError type
  • Full Tanstack query + Convex integration setup (you can use tanstack query with convex functions)
    • Global toasts for mutations states (opt in on mutation level)
  • Typesafe enviroment variables with T3 Env validated with Effect Schema
  • Basic utils (e.g tryCatch wrapper)
  • Light/dark mode setup (SSR safe)
  • Generic components like FullScreenLoading and FullScreenError
  • Prettier setup with plugins for organizing tailwind classess and imports

I'm still experimenting with the best way to make the effect code interact correctly with convex functions. For now, I created a utility to run an effect and wrap any failures in ConvexError and throw it. Then client can use parseConvexError util to read exact error message. This approach preserves the nature of js exceptions and doesn't break convex assumptions. This is how that looks like.

export const toggle = mutation({
  args: { id: v.id("todos") },
  handler: async ({ db }, { id }) => {
    const program = Effect.gen(function* () {
      const todoApi = yield* TodoApi
      const todo = yield* todoApi.getTodo({ db, todoId: id })
      yield* todoApi.toggleTodo({ db, todo })
    }).pipe(Effect.tapError((err) => Effect.logError(err)))

    return await runEffOrThrow(appRuntime, program)
  }
})

Media

Its really minimalistic, just a handy starter point

Todo

  • Add payments integration (Polar.sh)
  • Migrate from prettier to oxfmt
  • Add Posthog

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published