A better way to work on Salesforce
The Jetstream platform makes managing your Salesforce instances a breeze. Use Jetstream to work with your data and metadata to get your work done faster.
Learn more by reading the docs.
JETSTREAM IS SOURCE-AVAILABLE AND FREE TO USE. IF YOUR COMPANY IS GETTING VALUE, CONSIDER SPONSORING THE PROJECT ❤️
Jetstream wouldn't be possible without your contributions.
There are multiple ways to use Jetstream.
- Use the hosted version at https://getjetstream.app
- Run locally
- Using nodejs
- Building yourself (recommended if you want to contribute to the Jetstream codebase)
- Using Docker
- Using nodejs
- Want to self-host behind your company firewall? Reach out to the team for assistance.
This project was generated using Nx - This repository is considered a mono-repo and has multiple applications
├── app (This is used in the generation of the desktop application)
├── apps (Application)
│ ├── api (BACKEND NODE SERVER)
│ ├── cron-tasks
│ ├── docs (DOCS WEBSITE)
│ ├── jetstream (FRONTEND REACT APPLICATION)
│ ├── jetstream-e2e
│ ├── jetstream-worker
│ ├── landing (LANDING PAGE WEBSITE)
│ ├── maizzle (EMAIL TEMPLATE GENERATION)
│ └── ui-e2e
├── custom-typings
├── dist (FOLDER CREATED ONCE APPLICATION IS BUILT)
├── libs (CORE LIBRARIES SHARED ACROSS ALL APPLICATIONS)
│ ├── api-config
│ ├── connected (FRONTEND DATA LIBRARY)
│ ├── icon-factory (SFDC ICONS)
│ ├── monaco-configuration
│ ├── shared (SHARED UTILS ETC..)
│ ├── splitjs
│ ├── types (TYPESCRIPT TYPES)
│ └── ui (ANYTHING UI RELATED)
├── prisma (DB MIGRATIONS)
│ └── migrations
├── scripts
└── tools
└── generators
IF YOU HAVE ANY ISSUES WITH THE STEPS BELOW, PLEASE FILE A TICKET.
Pre-req
- Make sure you have node 24 installed.
- If you are using docker, make sure you have Docker installed.
- If you want to run the dev server, make sure you have pnpm installed. Corepack is recommended.
Run this script to copy .env.example to .env which will generate encryption keys which are required to run the application.
You will be asked some questions which will determine some of the environment variables.
pnpm scripts:generate-env📓 You can choose to skip authentication locally by setting the environment variable EXAMPLE_USER_OVERRIDE=true. This is set to true by default in the .env.example file.
🌟 To use this, don't click the login button, but instead just go to http://localhost:3333/app or http://localhost:4200/app (if running the react development server) directly.
If you have docker and just want to run the application locally, using docker is the easiest option.
Build the docker image (this takes a while the first time).
docker build -t jetstream-app .Use docker compose to create a dockerized postgres database and run the app.
docker compose up- Jetstream will be running at
http://localhost:3333 - Postgres will be running on port
5555if you wanted to connect to it locally. - You can login with the
Exampleuser- The username is
test@example.com - The password is contained in the
.envfile
- The username is
- If assets on the page don't load, do a hard refresh (hold cmd or shift and press refresh)
- This might happen if you have re-built the image and the browser has cached the page with now missing resources.
Use this option if you want to contribute to the codebase.
Jetstream relies on a Postgres database, so you either need to run Postgresql locally, in a docker container, or use a managed provider such as one from the list below. Optionally you can run jetstream in a Docker container which includes Postgresql.
- Render (Jetstream is hosted here)
- elephantsql
- AWS
- Azure
- GCP
You can use the example Salesforce OAuth2 client secret or client id, but you are welcome to create you own connected app in any Salesforce org of your choice.
If you want to create your own:
- Login to any org where you are an admin, usually a developer org or production org is best
- Setup > App Manager > New Connected App
- name it whatever you want
- Click "Enable OAuth Settings"
- Callback URL:
http://localhost:3333/oauth/sfdc/callback - Scopes:
- Access the identity URL service
id, profile, email, address, phone - Access unique user identifiers
openid - Manage user data via APIs
api - Perform requests at any time
refresh_token, offline_access
- Access the identity URL service
- All other defaults are fine
- Callback URL:
- Update the file named
.envand replaceSFDC_CONSUMER_KEYandSFDC_CONSUMER_SECRETwith the values from your connected app.
⭐ If you want to contribute to Jetstream, this is the best option.
- Install postgres
- ensure this is running with a database called
postgresand a user namedpostgreson default port 5432- If your database is cloud hosted or named something different, then you can adjust the environment variable in
.envafter you initialize your application and this file is created.
- If your database is cloud hosted or named something different, then you can adjust the environment variable in
- ensure this is running with a database called
- Install node 24
- Enable Corepack
- Run
corepack enable
- Run
- Install dependencies
- Run
pnpm installto install all dependencies
- Run
- Initialize
.envfilepnpm init:project(or manually copy.env.exampleto.env)- If you need to adjust your postges connection, you can do so now.
- Running in production mode
- Build application
pnpm build(this may take some time - if the build is cached in the cloud, this may run quickly)
- Start Jetstream
pnpm db:migrateto initialize databasepnpm db:seedto insert required records for the applicationnode dist/apps/api/main.js- Visit in a web browser - TODO: allow skipping auth
http://localhost:3333/app
- Build application
- Running in development mode - use this option if you want to work with the codebase
- Build required applications
pnpm build:landingpnpm db:generate
- Start Jetstream
- terminal 1:
pnpm start:apito start api server- This runs on
http://localhost:3333- most endpoints are prefixed at the/apipath
- This runs on
- terminal 2:
pnpm startto start the web development server- This runs on
http://localhost:4200and you will need to access the application herehttp://localhost:4200/app - The port is chosen at startup and printed in the terminal. If
4200is taken the next server picks4210, then4211, and so on, so several git worktrees can run a development server at the same time against the one api server. See Running several worktrees at once.
- This runs on
- terminal 1:
- Optional
pnpm start:ui:storybookto start the storybook server- This runs on
http://localhost:4400 - You can check out the public version of this at https://storybook.getjetstream.app
- This runs on
- Build required applications
Only one api server is needed no matter how many copies of the repo you have checked out. Start it once with
pnpm start:api, then run pnpm start in each worktree you want a web development server for. Every development
server proxies /api, /oauth, /socket.io and friends to that shared api server, so they all share one login
session, one database and one set of connected Salesforce orgs — switching between them requires no logging in and
no .env changes.
Ports are assigned automatically: the first server started takes 4200, and any others take 4210, 4211 and
upwards. 4201-4209 are never used, so they stay free for the desktop client (4201) and canvas (4202)
development servers.
Two environment variables override this when needed:
JETSTREAM_DEV_PORT- pin the development server to a specific port instead of searching for a free oneJETSTREAM_DEV_API_URL- proxy to an api server other thanhttp://localhost:3333
Giving a worktree its own api server is deliberately not supported. Connected orgs are stored against
JETSTREAM_SERVER_URL, so a second api server on a different port sees an empty org list and every org has to be
re-authorized, and the Salesforce and Google OAuth callback urls are registered against a specific port.
- Make sure you have Docker Desktop installed
- Run
docker compose upin your terminal- This may take a while the very first time
- If you make any changes, you need to re-build the application using
docker compose build
