Everything you need to run WindoM on your own machine.
This gets the extension running in Chrome with no backend needed. Clock, weather, todos, backgrounds, quotes, quick links, and the focus timer all work out of the box. Google Calendar and Spotify require the full stack setup below.
Clone the repository.
git clone https://github.com/YehudaBriskman/WindoM.git
cd WindoM
Install dependencies for the extension.
cd web
npm install
Build the extension.
npm run build
This creates a web/dist/ folder - that is your built extension.
Load the extension in Chrome.
chrome://extensionsweb/dist folderOpen a new tab. WindoM should appear.
npm run dev instead of build, then load the web/ project root folder (not dist/) as the unpacked extension at chrome://extensions. Changes reload automatically via HMR.
Required if you want Google Calendar sync or Spotify integration. This runs a local backend with a Postgres database using Docker.
Copy the example environment file.
cp backend/.env.example backend/.env
Then open backend/.env and fill in the values. See the Environment Reference below for what each one means.
Generate secure secrets for JWT and token encryption.
node -e "const c=require('crypto'); console.log('JWT_ACCESS_SECRET='+c.randomBytes(32).toString('base64')); console.log('REFRESH_TOKEN_SECRET='+c.randomBytes(32).toString('base64')); console.log('TOKEN_ENC_KEY_BASE64='+c.randomBytes(32).toString('base64'));"
Copy the output into your .env file.
Start the backend and database with Docker.
docker-compose up --build
The API will be running at http://localhost:8080. The database runs at port 5433.
Build the extension pointing at your local backend.
cd web
npm install
npm run build
The default backend URL is already http://localhost:8080 so no changes are needed.
Load web/dist as an unpacked extension in Chrome (same as Option A, step 4).
http://localhost:8080/auth/google/callbackhttp://localhost:8080/oauth/google/callback
http://localhost:8080/oauth/spotify/callback
All variables go in backend/.env. The ones marked optional are only needed for specific features.
| Variable | Description | Required |
|---|---|---|
PORT |
Port the backend listens on. Default: 8080 |
No |
DATABASE_URL |
Postgres connection string. When using Docker Compose this is set automatically. | Yes |
JWT_ACCESS_SECRET |
Random secret used to sign access tokens. Generate with openssl rand -base64 32 |
Yes |
REFRESH_TOKEN_SECRET |
Random secret used to sign refresh tokens. Generate separately from the above. | Yes |
TOKEN_ENC_KEY_BASE64 |
32 random bytes base64-encoded. Used to encrypt OAuth tokens at rest. | Yes |
GOOGLE_CLIENT_ID |
OAuth 2.0 Client ID from Google Cloud Console. | For Google features |
GOOGLE_CLIENT_SECRET |
OAuth 2.0 Client Secret from Google Cloud Console. | For Google features |
GOOGLE_REDIRECT_URI |
Callback URL for Google Sign-in. Example: http://localhost:8080/auth/google/callback |
For Google features |
GOOGLE_OAUTH_REDIRECT_URI |
Callback URL for Google Calendar OAuth. Example: http://localhost:8080/oauth/google/callback |
For Calendar |
SPOTIFY_CLIENT_ID |
Client ID from your Spotify Developer app. | For Spotify |
SPOTIFY_CLIENT_SECRET |
Client Secret from your Spotify Developer app. | For Spotify |
SPOTIFY_REDIRECT_URI |
Callback URL for Spotify OAuth. Example: http://localhost:8080/oauth/spotify/callback |
For Spotify |
CORS_ALLOWED_ORIGINS |
Comma-separated list of allowed origins. Include your extension ID and localhost ports. | Yes |
EXTENSION_REDIRECT_BASE |
The chromiumapp.org URL for your extension. Used as the OAuth redirect base for the Chrome identity flow. | For Google features |
SMTP_USER |
Google Workspace email address used to authenticate with Gmail SMTP. Must have a Google App Password. If not set, emails are printed to the console instead of sent. | No |
SMTP_PASS |
16-character Google App Password for the SMTP account. Generate at myaccount.google.com → Security → 2-Step Verification → App Passwords. | No |
FROM_EMAIL |
The "From" address shown on outbound emails. Must be the same as SMTP_USER or an alias of it. Defaults to noreply@windom.app. |
No |
APP_URL |
Public base URL of the backend. Used to build email verification and password-reset links. Example: http://localhost:8080. |
No |
chrome://extensions. The ID is shown under the extension name. Use it in CORS_ALLOWED_ORIGINS as chrome-extension://YOUR_ID and in EXTENSION_REDIRECT_BASE as https://YOUR_ID.chromiumapp.org.
docker-compose up, the DATABASE_URL is automatically overridden to point to the db container (port 5432 internally). You only need to set it manually if you run the backend directly on your host, in which case use port 5433 - the host-mapped port Docker Compose exposes.
PORT=8080
NODE_ENV=development
DATABASE_URL=postgresql://windom:windom@localhost:5433/windom
JWT_ACCESS_SECRET=your-generated-secret-here
REFRESH_TOKEN_SECRET=your-other-generated-secret-here
TOKEN_ENC_KEY_BASE64=your-generated-key-here
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=http://localhost:8080/auth/google/callback
GOOGLE_OAUTH_REDIRECT_URI=http://localhost:8080/oauth/google/callback
SPOTIFY_CLIENT_ID=your-spotify-client-id
SPOTIFY_CLIENT_SECRET=your-spotify-client-secret
SPOTIFY_REDIRECT_URI=http://localhost:8080/oauth/spotify/callback
CORS_ALLOWED_ORIGINS=chrome-extension://YOUR_EXTENSION_ID,http://localhost:3000,http://localhost:5173
EXTENSION_REDIRECT_BASE=https://YOUR_EXTENSION_ID.chromiumapp.org
# Email - optional. If omitted, verification/reset emails are printed to the console.
# SMTP_USER=you@yourdomain.com
# SMTP_PASS=your-16-char-app-password
# FROM_EMAIL=noreply@windom.app
# APP_URL=http://localhost:8080