The open-source operating system for manufacturing
Discord · Website · Issues
Does the world need another ERP?
We built Carbon after years of building end-to-end manufacturing systems with off-the-shelf solutions. We realized that:
Modern, API-first tooling didn't exist
Vendor lock-in bordered on extortion
There is no "perfect ERP" because each company is unique
We built Carbon to solve these problems ☝️.
Architecture
Carbon is designed to make it easy for you to extend the platform by building your own apps through our API. We provide some examples to get you started in the examples folder.
Features:
ERP
ERP MES
MES QMS
QMS Custom Fields
Custom Fields Nested BoM
Nested BoM Traceability
Traceability MRP
MRP Configurator
Configurator MCP Client/Server
MCP Client/Server API
API Webhooks
Webhooks Accounting
Accounting Capacity Planning
Capacity Planning Simulation
Technical highlights:
Unified auth and permissions across apps
Unified auth and permissions across apps Full-stack type safety (Database → UI)
Full-stack type safety (Database → UI) Realtime database subscriptions
Realtime database subscriptions Attribute-based access control (ABAC)
Attribute-based access control (ABAC) Role-based access control (Customer, Supplier, Employee)
Role-based access control (Customer, Supplier, Employee) Row-level security (RLS)
Row-level security (RLS) Composable user groups
Composable user groups Dependency graph for operations
Dependency graph for operations Third-party integrations
Techstack
Remix – framework
Typescript – language
Tailwind – styling
Radix UI - behavior
Supabase - database
Supabase – auth
Upstash - cache
Trigger - jobs
Resend – email
Novu – notifications
Vercel – hosting
Stripe - billing
Codebase
The monorepo follows the Turborepo convention of grouping packages into one of two folders.
/apps for applications /packages for shared code
Package Name Description Local Command erp ERP Application npm run dev mes MES npm run dev:mes academy Academy npm run dev:academy starter Starter npm run dev:starter
Package Name Description eslint-config-carbon Shared, extendable eslint configuration for apps and packages @carbon/database Database schema, migrations and types @carbon/documents Transactional PDFs and email templates @carbon/integrations Integration definitions and configurations @carbon/jest Jest preset configuration shared across apps and packages @carbon/jobs Background jobs and workers @carbon/logger Shared logger used across apps @carbon/react Shared web-based UI components @carbon/kv Redis cache client @carbon/lib Third-party client libraries (slack, resend) @carbon/stripe Stripe integration @carbon/tsconfig Shared, extendable tsconfig configuration used across apps and packages @carbon/utils Shared utility functions used across apps and packages
Development
Setup
Clone the repo into a public GitHub repository (or fork https://github.com/crbnos/carbon/fork). If you plan to distribute the code, keep the source code public to comply with AGPLv3. To clone in a private repository, acquire a commercial license git clone https://github.com/crbnos/carbon.git Go to the project folder cd carbon
Make sure that you have Docker installed on your system since this monorepo uses the Docker for local development.
In addition you must configure the following external services:
Service Purpose URL Upstash Serverless Redis https://console.upstash.com/login Trigger.dev Job runner https://cloud.trigger.dev/login Posthog Product analytics platform https://us.posthog.com/signup
Each of these services has a free tier which should be plenty to support local development. If you're self hosting, and you don't want to use Upstash or Posthog, it's pretty easy to replace upstash with a redis container in @carbon/kv and remove the Posthog analytics.
Installation
First download and initialize the repository dependencies.
$ nvm use # use node v20 $ npm install # install dependencies $ npm run db:start # pull and run the containers
Create an .env file and copy the contents of .env.example file into it
$ cp ./.env.example ./.env
Use the output of npm run db:start to set the supabase entries:
SUPABASE_SERVICE_ROLE_KEY=[service_role key]
SUPABASE_ANON_KEY=[anon key]
Create a Redis database in upstash and copy the following from the REST API section:
UPSTASH_REDIS_REST_URL=[UPSTASH_REDIS_REST_URL]
UPSTASH_REDIS_REST_TOKEN=[UPSTASH_REDIS_REST_TOKEN]
Navigate to the project you created in https://cloud.trigger.dev/ and copy the following from the Environments & API Keys section:
TRIGGER_PUBLIC_API_KEY=[Public 'dev' API Key, starting 'pk_dev*']
TRIGGER_API_KEY=[Server 'dev' API Key, starting 'tr_dev*']
In Posthog go to https://[region].posthog.com/project/[project-id]/settings/project-details to find your Project ID and Project API key:
POSTHOG_API_HOST=[https://[region].posthog.com]
POSTHOG_PROJECT_PUBLIC_KEY=[Project API Key starting 'phc*']
Add a STRIPE_SECRET_KEY from the Stripe admin interface, and then run npm run -w @carbon/stripe register:stripe to get a STRIP_WEBHOOK_SECRET
STRIPE_SECRET_KEY="sk_test_*************"
STRIP_WEBHOOK_SECRET="whsec_************"
Then you can run the following:
$ npm run db:build # run db migrations and seed script $ npm run build # build the packages
Finally, start the apps and packages:
$ npm run dev $ npm run dev:mes # npm run dev in all apps & packages
You can now sign in with:
username: [email protected] password: carbon
After installation you should be able run the apps locally.
Application URL ERP http://localhost:3000 MES http://localhost:3001 Academy http://localhost:4111 Starter http://localhost:4000 Postgres postgresql://postgres:postgres@localhost:54322/postgres Supabase Studio http://localhost:54323/project/default Mailpit http://localhost:54324 Edge Functions http://localhost:54321/functions/v1/
Notes
To kill the database containers in a non-recoverable way, you can run:
$ npm run db:kill # stop and delete all database containers
To restart and reseed the database, you can run:
$ npm run db:build # runs db:kill, db:start, and setup
To run a particular application, use the -w workspace flag.
For example, to run test command in the @carbon/react package you can run:
$ npm run test -w @carbon/react
API
The API documentation is located in the ERP app at ${ERP}/x/api/js/intro . It is auto-generated based on changes to the database.
There are two ways to use the API:
From another codebase using a supabase client library:
From within the codebase using our packages.
From another Codebase
Navigate to settings in the ERP to generate an API key. If you're self-hosting you can also use the supabase service key instead of the public key for root access. In that case you don't needto include the carbon-key header.
import { Database } from "@carbon/database" ; import { createClient } from "@supabase/supabase-js" ; const apiKey = process . env . CARBON_API_KEY ; const apiUrl = process . env . CARBON_API_URL ; const publicKey = process . env . CARBON_PUBLIC_KEY ; const carbon = createClient < Database > ( apiUrl , publicKey , { global : { headers : { "carbon-key" : apiKey , } , } , } ) ; // returns items from the company associated with the api key const { data , error } = await carbon . from ( "item" ) . select ( "*" ) ;
From the Monorepo