Long Habit is a simple CRUD application for tracking long-term habits and recurring tasks. It is a production-ready full-stack project built using PocketBase and React. This is a comprehensive example of integrating PocketBase into a larger Go project and combining it with a modern React frontend using best practices. The application is very simple and can be used as a template for starting new projects. Most of the boilerplate setup has been taken care of and common issues have been identified and fixed.
Try the live version: https://longhabit.com
- Running the latest version of Pocketbase (v0.24).
- Single-binary build. Uses Go's "embed" package to embed the React front-end as a file system inside the compiled binary.
- PocketBase is installed as a Go package and used as a framework. The project makes use of many extension features including:
- Custom hooks and middleware
- Route binding
- Database operations
- Scheduled tasks with cron
- HTML email templates
- Custom logging configuration
- Worker pool implementation for bulk email processing done using the Pond library
- Idiomatic Go code organization with clean separation of concerns
- Modern React setup with TypeScript and Vite.
- Built for React 19. Works with React Compiler enabled.
- TailwindCSS with ShadCN UI fully configured with a custom theme.
- Responsive design using all the best practices. Supports light and dark mode. Tested on desktop and mobile screens.
- Complete authentication flow with customized forms. Works with email + password auth as well as Google OAuth.
- TanStack Router configured using best practices. All the authentication logic and data fetching happens in the router before the pages are loaded. Dynamic page title switching based on route.
- TanStack Query fully integrated with PocketBase and TanStack Router. Fresh data is fetched from the backend and loaded before the routes are rendered. TanStack Query takes care of data fetching and ensures that client-side state is up to date with server-side data.
- Loading states are implemented using the new React Suspense boundaries.
- Dynamic forms with validation and error messages implemented using React Hook Form and Zod.
- SEO optimizations like meta description and social media cards meta tags added to root HTML page, sitemap.xml and robots.txt added and configured. Exclude rule for the PocketBase admin "/_" URL added to prevent it from being indexed by crawlers.
- Vite dev mode with hot reload works seamlessly with PocketBase. No need to wait for PocketBase to compile. Vite and PocketBase proxy requests to and from each other while running on different ports.
- Fully working ESlint configuration written in the new ESlint 9 format. Includes all the relevant plugins for React, Tailwind and Prettier.
- Single-command production builds.
- Run project locally in Docker Compose without additional configuration.
- Compatible with any Node.js runtime (default: Bun).
- Compile into a single executable binary or deploy using Docker containers.
- Fully containerized, all the build steps happen in a multi-stage Dockerfile. Outputs a slim Alpine container that contains only the compiled binary.
- Docker Compose deployment that works out of the box. Working health check endpoint included.
- Ready for deployment on Dokploy, Coolify and similar platforms.
- Frontend
- TypeScript - Frontend language
- React 19 - Frontend framework
- Vite - Build tool
- TanStack Router - Router
- TanStack Query - Data fetching and state management
- TanStack Table - Table / data grid library
- React Hook Form - Forms library for React
- shadcn/ui - React component library based on TailwindCSS and Radix UI
- TailwindCSS - Utility-first CSS framework
- Zod - Typescript schema validation
- Date-fns - Date manipulation library
- Backend
- Go 1.23 - Backend language
- PocketBase - Backend framework
- Pond - Worker pool implementation in Go
- Deployment
- Go 1.23+
- Node.js 18+ or Bun
- Docker (optional)
- Clone the repository
git clone https://github.com/s-petr/longhabit
- Install dependencies
npm install --legacy-peer-deps
orbun install
. The--legacy-peer-deps
tag will silence peer dependency conflicts in NPM. The UI library shadcn.ui uses an older version of react-day-picker for the calendar. It works fine but will throw a dependency conflict with React 19. This is a temporary issue that will go away with future updates. - Create a new superuser (admin) account for the Pocketbase admin dashboard. First compile the binary
npm run build
orbun run build
. Then run the command./longhabit superuser upsert {{admin email}} {{admin password}}
- Once the PocketBase backend is up and running you need to set up the database tables. Log in to the Pocketbase dashboard
http://localhost:8090/_/
using your superuser credentials. Go to Settings -> Import collections -> Load from JSON file. Select file backend/pb_schema.json and import it. - A folder
/db
will be created in the root directory. This will contain the database files. Docker Compose has been configured with a volume to read/write data to the same folder. You may need to adjust file permissions for this folder if PocketBase cannot write to it from the Docker container.
- Start development servers
npm run dev
orbun run dev
- Build frontend and backend
npm run build
orbun run build
- Run the compiled binary
npm run preview
orbun run preview
- Build and run with Docker Compose
npm run compose
orbun run compose
This project is licensed under the MIT License - see the LICENSE.md file for details.