OpenStock is an open source, self-hostable stock market dashboard built by the Open Dev Society as a free alternative to paid market platforms: it gives you live quotes, candlestick and technical charts, a market heatmap and top stories through TradingView's embeddable widgets, stock search and company profiles through the Finnhub API, a per-user watchlist with above/below price alerts stored in MongoDB, and AI-personalized welcome and news-digest emails sent through Inngest jobs. It is trending on GitHub today with roughly 480 new stars on top of about 15,900 total, a year after its first commit in September 2025, under the AGPL-3.0 license. A working local install takes around 20 minutes on any machine with Node.js 20 and Docker: clone the repo, install dependencies, start a MongoDB container, paste a free Finnhub key and a generated auth secret into .env, run the dev server and register the first account at http://localhost:3000.
- The stack is Next.js 15 with React 19, TypeScript, Tailwind v4 and shadcn/ui on the front, Better Auth plus MongoDB for accounts, Finnhub for data, TradingView for charts, and Inngest for background jobs. There is no packaged release: you run it from source or build the Docker image yourself.
- Only three things are truly required to get to a working dashboard: a MongoDB connection string, a
BETTER_AUTH_SECRET, and a free Finnhub API key. Gmail and Gemini credentials only matter for the email features, and sign-up succeeds even if the email job fails. - The free Finnhub tier is rate limited to 60 calls per minute, quotes for non-US stocks are delayed 15 minutes or more, and TradingView's free widgets refuse some emerging-market symbols (India NSE included) with an "only available on TradingView" message.
- Every route except sign-in, sign-up and password reset sits behind a session cookie check in
middleware/index.ts, so the first thing you see atlocalhost:3000is the sign-in page, not the dashboard.
The exact steps, start to finish
- Step 1. Check what you already have.
The README lists Node.js 20+ and pnpm or npm as the prerequisites, a MongoDB connection string (Atlas or the local Docker Compose service), a Finnhub API key, a Gmail account for outgoing mail, and optionally a Gemini key. If you would rather not run Docker, a free MongoDB Atlas cluster works too; the only difference is the connection string in Step 4.# OpenStock needs Node.js 20+ with npm or pnpm, Git, and Docker for the bundled MongoDB. node --version npm --version git --version docker --version docker compose version - Step 2. Clone the repo and install dependencies. These are the README's exact lines:
The install pulls Next.js 15.5.7, React 19.1, Mongoose 8, Better Auth 1.3, Inngest 3.47 and Nodemailer 7 fromgit clone https://github.com/Open-Dev-Society/OpenStock.git cd OpenStock # choose one: pnpm install # or npm installpackage.json. On our test machinenpm installadded 726 packages in 54 seconds and ended with an audit notice listing 71 advisories, five of them critical, in transitive dependencies; expected for a Next.js app with a lock file from July, but runnpm auditbefore exposing it. - Step 3. Start MongoDB. The repository ships a
docker-compose.ymlwith amongodbservice (imagemongo:7, root userroot, passwordexample, a persistentmongo-datavolume and amongoshhealth check). From the repo root, start just that service first, exactly as the README's Docker section shows:
It publishes port 27017 on your machine. Skip this step if you are using Atlas.# from the repository root docker compose up -d mongodb - Step 4. Get a free Finnhub key. Register at finnhub.io/register (free, no card) and copy the API key from the dashboard at finnhub.io/dashboard. The README notes the free tier is supported and that real-time data may require a paid plan; the project's
MARKET_SUPPORT.mdadds that the free tier is capped at 60 API calls per minute. - Step 5. Create
.envat the project root. There is no.env.examplein the repo, so create the file yourself with the variable names from the README's Environment Variables section. This is the minimum that gets you to a working dashboard when you run the dev server on your own machine against the Docker MongoDB:
One deliberate change from the README's Docker example: the README writes the host as# Core NODE_ENV=development # Database (Docker) MONGODB_URI=mongodb://root:example@localhost:27017/openstock?authSource=admin # Better Auth BETTER_AUTH_SECRET=your_better_auth_secret BETTER_AUTH_URL=http://localhost:3000 # Finnhub NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_key FINNHUB_BASE_URL=https://finnhub.io/api/v1 # Gemini GEMINI_API_KEY=your_gemini_api_key # Inngest Signing Key (required for Vercel deployment) INNGEST_SIGNING_KEY=your_inngest_signing_key # Email (Nodemailer via Gmail; consider App Passwords if 2FA) NODEMAILER_EMAIL=youraddress@gmail.com NODEMAILER_PASSWORD=your_gmail_app_passwordmongodb, which only resolves inside the Compose network. When the app runs withnpm run devon your host and only MongoDB is in Docker, the host islocalhost. Generate the auth secret with the command Better Auth's own installation guide gives,openssl rand -base64 32(Git Bash or WSL on Windows), and paste it afterBETTER_AUTH_SECRET=. Paste your Finnhub key afterNEXT_PUBLIC_FINNHUB_API_KEY=. The Gemini, Inngest and Gmail lines can stay as placeholders for a first run; fill them later from aistudio.google.com/app/apikey, app.inngest.com/env/settings/keys and a Gmail App Password if you want the emails. - Step 6. Verify the database connection.
The script (pnpm test:db # or npm run test:dbscripts/test-db.mjs) loads.env, connects with Mongoose and printsOK: Connected to MongoDB [db="openstock", host="localhost", time=...ms]. Ignore theDNS SRV Recordsblock printed around it: the script also looks up a hard-coded Atlas hostname, which has nothing to do with your local database. In our test the connection came back in 44 ms. If it printsERROR: Database connection failed, yourMONGODB_URIis wrong or the container is not up (docker compose ps). - Step 7. Run the dev server.
Next.js prints# Next.js dev (Turbopack) pnpm dev # or npm run devLocal: http://localhost:3000after a few seconds. Leave this terminal open. - Step 8. Optional: run Inngest locally for the background jobs. In a second terminal, the README's line is:
The Inngest dev server opens a dashboard on port 8288, discovers the app's functions atnpx inngest-cli@latest dev/api/inngest, and runs the welcome-email job on sign-up, the alert checker every five minutes, and the scheduled news summaries. You can skip it entirely for a first look; the sign-up code catches a failed event send and continues. In our test it did not get further than that anyway: the dev server (inngest-cli 1.45.1) refused to sync the app withApp sync was blocked because this application is using an Inngest JavaScript SDK with a known security vulnerability. Please upgrade to v3.54.0 or later, because the lock file pinsinngest@3.47.0, which is inside the CVE-2026-42047 range Inngest disclosed. Upgrading to 3.54.2 got past the block, but then every function was rejected withConfig invalid ... Invalid input, so the four jobs (welcome email, weekly summary, alert check, inactive-user check) will need a maintainer fix before they run locally. - Step 9. Register the first account and use the dashboard. Open
http://localhost:3000. The middleware redirects you to/sign-in; click through to sign up with a name, email and password (8 characters minimum, no email verification is required) and answer the onboarding questions (country, investment goals, risk tolerance, preferred industry). Better Auth auto-signs you in and lands you on the market overview with the TradingView heatmap, quote lists and stories. Press Ctrl+K (Cmd+K on a Mac) or click Search, typeAAPL, open the stock page, and clickAdd to Watchlist; it flips toRemove from Watchlistand the symbol is stored in MongoDB. When the symbol shows up on/watchlistwith a live price and an option to set an above/below alert, OpenStock is working end to end. Both the search results and the watchlist page depend on the Finnhub key being real: with a placeholder, search returns nothing and/watchlistshowsApplication error: a server-side exception has occurredbecause its server-side news fetch gets a 401 from Finnhub. The dashboard and the stock page still render, because their charts come from TradingView.
npm run dev wires together: the Next.js app in the middle owns auth and the watchlist in MongoDB, pulls data from Finnhub, lets the browser load TradingView widgets directly, and hands email and alert work to Inngest.What is OpenStock and why is it trending?
OpenStock is the flagship project of the Open Dev Society, a community that publishes free tools under a manifesto about knowledge without paywalls. The app grew out of Adrian Hajdin's JavaScript Mastery stock-market tutorial (the README credits it directly), and lead developer ravixalgorithm turned it into a complete product: email and password accounts through Better Auth with a MongoDB adapter, protected routes via Next.js middleware, a Cmd+K command palette that searches Finnhub with debounced queries and shows popular tickers when idle, a stock page with TradingView symbol info, candlestick and advanced charts, technicals, company profile and financials, a watchlist with a unique symbol per user, and price alerts that a five-minute Inngest cron checks. An optional Adanos integration adds a sentiment card that pulls Reddit, X, news and Polymarket signals.
RelatedWeKnora Setup: Self-Host Tencent's Open Source RAG Platform
Why the spike now: the repository has been sitting on the trending page for days on the back of a README refresh (the last two commits are README edits on September 18 and 19), the Open Dev Society is cross-promoting it from its new kitbash project, and self-hosted personal finance tooling is a crowded but under-served category where most alternatives either cost money or are portfolio trackers rather than market dashboards. OpenStock is candid about its limits: the README says it is community-built, not a brokerage, that data may be delayed depending on your provider, and that nothing in it is financial advice.
How do you install OpenStock on Windows?
Install Node.js 20 LTS or newer, Git for Windows and Docker Desktop, start Docker Desktop, then run the README's commands in PowerShell:
# PowerShell
git clone https://github.com/Open-Dev-Society/OpenStock.git
cd OpenStock
npm install
docker compose up -d mongodb
npm run test:db
npm run dev
# cmd.exe (identical; the commands are the same in both shells)
git clone https://github.com/Open-Dev-Society/OpenStock.git
cd OpenStock
npm install
docker compose up -d mongodb
npm run test:db
npm run dev
Create the .env file from Step 5 before test:db. Windows has no openssl in PowerShell or cmd by default; run openssl rand -base64 32 inside Git Bash (installed with Git for Windows) and paste the result. Port 3000 must be free; Next.js will move to 3001 if it is not, but then BETTER_AUTH_URL in .env has to match or sign-in cookies will not be set.
How do you install OpenStock on macOS and Linux?
On a Mac, install Node.js 20+ (Homebrew or the official installer), Git and Docker Desktop or OrbStack, then run the same lines from Step 2 through Step 7. Apple Silicon is fine: mongo:7 is multi-arch and the app is plain Node. On Linux, install Node.js 20+, Git, Docker Engine and the Compose plugin, add your user to the docker group, and run the same commands. openssl is present on both platforms, so the auth secret is one command away.
If you would rather run everything in containers, the README's full Docker path is two commands from the repo root, with .env pointing at the Compose hostname instead of localhost (MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin):
# from the repository root
docker compose up -d mongodb && docker compose up -d --build
The Dockerfile is a single-stage node:20-alpine image that runs npm install, npm run build and npm start, so the first build takes several minutes and the image is not small. The README also warns not to hard-code secrets in the Dockerfile: the app service reads .env through env_file, which is exactly why the file has to exist before --build.
For production, the README's build-and-start lines are pnpm build && pnpm start or npm run build && npm start. A note in the env section says NEXT_PUBLIC_FINNHUB_API_KEY and INNGEST_SIGNING_KEY are required for a Vercel deployment, and that in production you should prefer a dedicated SMTP provider over a personal Gmail.
How does OpenStock compare with Ghostfolio, Portfolio Performance and a brokerage app?
| Trait | OpenStock | Ghostfolio | Portfolio Performance | Typical broker app |
|---|---|---|---|---|
| What it is | Market dashboard, watchlist, alerts | Portfolio and wealth tracker | Desktop portfolio accounting | Trading plus research |
| Licence | AGPL-3.0 | AGPL-3.0 | EPL-1.0 | Proprietary |
| Runs where | Node.js or Docker, self-hosted | Docker, self-hosted or cloud | Java desktop app | Their servers |
| Data source | Finnhub plus TradingView widgets | Yahoo Finance and others | Multiple quote feeds | Exchange feeds |
| Charts | TradingView embeds | Built in | Built in | Built in |
| Price alerts | Yes, via Inngest cron | No | No | Yes |
| Holdings and P&L | No, watchlist only | Yes | Yes | Yes |
| Setup effort | Node, MongoDB, one API key | Docker Compose | Installer | Account and KYC |
The comparison makes the positioning clear. Ghostfolio and Portfolio Performance are about what you own; OpenStock is about what you are watching. If you want a private, ad-free screen with charts, a heatmap, a watchlist and alerts, and you do not need to log trades or compute returns, OpenStock is the lighter fit. If you need holdings, cost basis and performance, pick one of the other two.
What are the gotchas before you rely on it?
Data limits are the product's limits. Everything you see comes from a free Finnhub key and free TradingView widgets. That means 60 calls a minute, delayed quotes outside the US, no forex, no crypto and no Chinese A-shares on the free tier, and a "This symbol is only available on TradingView" error on some Indian, Vietnamese, Philippine and Indonesian tickers. The MARKET_SUPPORT.md file lists the 30-plus exchanges that do work and suggests upgrading the API keys in .env or swapping in a chart library if you need more.
The Finnhub key is public. The variable is named NEXT_PUBLIC_FINNHUB_API_KEY and the README reminds you that NEXT_PUBLIC_ variables are shipped to the browser. Anyone who can load your instance can read that key. Fine on your laptop; think twice before putting it on a public domain.
RelatedEver Gauzy Setup: Self-Host an Open Source ERP and CRM
No .env.example, and the README's Docker URI is not for local dev. You have to assemble .env by hand from the README, and if you copy the Compose block's @mongodb:27017 host into a setup where only MongoDB runs in Docker, the app cannot resolve it. Use localhost there. The repo's scripts/check-env.mjs prints which required variables are missing, but it reads the process environment rather than .env, so on Node 20.6 or newer run it as node --env-file=.env scripts/check-env.mjs; plain node scripts/check-env.mjs reports everything missing.
Background jobs are broken as shipped. The Inngest dev server blocks the pinned inngest@3.47.0 SDK outright (CVE-2026-42047, fixed in 3.54.0), and the 3.54 line rejects the repo's function definitions as invalid config. Alerts and email digests are on the box, but until the maintainers bump and fix the SDK usage they do not run. If you run the production build locally with npm run build && npm start, add INNGEST_DEV=1 to the environment as well: with NODE_ENV=production the SDK assumes Inngest Cloud and the local dev server reports Expected server kind cloud, got dev.
Email needs a Gmail App Password. Nodemailer is wired for Gmail, and the README says to use an App Password if two-factor authentication is on (it is, on most accounts). Password reset emails go through the same transport, so with placeholders in place the forgot-password flow will not deliver anything, and every server start logs Nodemailer transporter verification failed: Invalid login: 535-5.7.8. It is noisy but harmless.
The cron schedule in the code is not quite what the README says. The README describes a daily 12:00 news summary; lib/inngest/functions.ts currently registers a weekly Monday 9 AM summary, a five-minute alert check and a daily inactive-user check. Treat the code as the truth, and remember that none of these run unless the Inngest dev server (or a signed Inngest deployment) is attached.
AGPL-3.0 and no releases. If you modify OpenStock and host it for other people, the license requires you to publish your changes. And with no tagged releases, git pull is your upgrade path, so pin a commit if you care about reproducibility.
- An
.env.exampleand a release. Both are missing today and both would cut first-run friction in half. Thecheck-env.mjsscript shows the maintainers know which variables matter. - Chart independence. The market-support doc floats Lightweight Charts or Chart.js as a way around TradingView's free-tier symbol gaps; that would make emerging-market coverage a data question rather than a widget one.
- Holdings. Alerts and a watchlist are the current ceiling. A positions table would move it into Ghostfolio territory and is the most requested kind of feature for this category.
Our take
OpenStock is a well-built, honest dashboard rather than a finance platform, and that is the right ambition for a community project. The stack is modern and readable (Next.js 15, server actions, Better Auth, Mongoose models you can open and understand), the UI is genuinely pleasant, and the twenty-minute path to a working watchlist is real once you know that only three environment variables matter on day one. The weaknesses are mostly upstream: free-tier data delays and TradingView's symbol restrictions decide what you can see, not the code. If you want a private market screen you control, with alerts that email you, it is worth the afternoon. If you want to track a portfolio, pair it with Ghostfolio instead of waiting for OpenStock to grow into one.
- OfficialOpen-Dev-Society/OpenStock repository, README quick start, Docker section and environment variables
- OfficialOpenStock releases page no tagged releases at the time of writing
- OfficialMARKET_SUPPORT.md supported exchanges, Finnhub and TradingView free-tier limits, troubleshooting
- Officialdocker-compose.yml mongodb service definition, credentials and volume
- Officialopenstock-ods.vercel.app hosted demo instance
- ReferenceFinnhub registration free API key the app requires
- ReferenceBetter Auth installation guide BETTER_AUTH_SECRET generation with openssl rand -base64 32
Original analysis by GenZTech. Tool documentation: Open-Dev-Society/OpenStock on GitHub.
