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 at localhost:3000 is the sign-in page, not the dashboard.

The exact steps, start to finish

  1. Step 1. Check what you already have.
    # 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
    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.
  2. Step 2. Clone the repo and install dependencies. These are the README's exact lines:
    git clone https://github.com/Open-Dev-Society/OpenStock.git
    cd OpenStock
    
    # choose one:
    pnpm install
    # or
    npm install
    The install pulls Next.js 15.5.7, React 19.1, Mongoose 8, Better Auth 1.3, Inngest 3.47 and Nodemailer 7 from package.json. On our test machine npm install added 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 run npm audit before exposing it.
  3. Step 3. Start MongoDB. The repository ships a docker-compose.yml with a mongodb service (image mongo:7, root user root, password example, a persistent mongo-data volume and a mongosh health check). From the repo root, start just that service first, exactly as the README's Docker section shows:
    # from the repository root
    docker compose up -d mongodb
    It publishes port 27017 on your machine. Skip this step if you are using Atlas.
  4. 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.md adds that the free tier is capped at 60 API calls per minute.
  5. Step 5. Create .env at the project root. There is no .env.example in 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:
    # 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_password
    One deliberate change from the README's Docker example: the README writes the host as mongodb, which only resolves inside the Compose network. When the app runs with npm run dev on your host and only MongoDB is in Docker, the host is localhost. 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 after BETTER_AUTH_SECRET=. Paste your Finnhub key after NEXT_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.
  6. Step 6. Verify the database connection.
    pnpm test:db
    # or
    npm run test:db
    The script (scripts/test-db.mjs) loads .env, connects with Mongoose and prints OK: Connected to MongoDB [db="openstock", host="localhost", time=...ms]. Ignore the DNS SRV Records block 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 prints ERROR: Database connection failed, your MONGODB_URI is wrong or the container is not up (docker compose ps).
  7. Step 7. Run the dev server.
    # Next.js dev (Turbopack)
    pnpm dev
    # or
    npm run dev
    Next.js prints Local: http://localhost:3000 after a few seconds. Leave this terminal open.
  8. Step 8. Optional: run Inngest locally for the background jobs. In a second terminal, the README's line is:
    npx inngest-cli@latest dev
    The Inngest dev server opens a dashboard on port 8288, discovers the app's functions at /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 with App 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 pins inngest@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 with Config 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.
  9. 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, type AAPL, open the stock page, and click Add to Watchlist; it flips to Remove from Watchlist and the symbol is stored in MongoDB. When the symbol shows up on /watchlist with 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 /watchlist shows Application error: a server-side exception has occurred because its server-side news fetch gets a 401 from Finnhub. The dashboard and the stock page still render, because their charts come from TradingView.
What a self-hosted OpenStock install talks toA browser talks to the Next.js 15 app on port 3000, which stores users, watchlists and alerts in MongoDB, fetches search results and company data from the Finnhub API, embeds TradingView widgets for charts, and hands background jobs to Inngest, which calls Gemini and sends email through Nodemailer over Gmail. NPM RUN DEV Your browserlocalhost:3000 OpenStock appNext.js 15, React 19Better Auth, server actions Finnhub APIsearch, profiles, news TradingViewcharts, heatmap widgets widgets load straight from TradingView in the browser MongoDB 7docker compose up -d mongodbusers, watchlists, alerts Inngest jobsnpx inngest-cli@latest devwelcome email, alerts, digests Gemini Gmail Required for a working dashboard: MongoDB, BETTER_AUTH_SECRET, a free Finnhub key. Everything on the right is optional. Free-tier limits: 60 Finnhub calls a minute, 15 min delayed quotes outside the US, some TradingView symbols blocked. genztech.blog
Fig 1 What 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?

TraitOpenStockGhostfolioPortfolio PerformanceTypical broker app
What it isMarket dashboard, watchlist, alertsPortfolio and wealth trackerDesktop portfolio accountingTrading plus research
LicenceAGPL-3.0AGPL-3.0EPL-1.0Proprietary
Runs whereNode.js or Docker, self-hostedDocker, self-hosted or cloudJava desktop appTheir servers
Data sourceFinnhub plus TradingView widgetsYahoo Finance and othersMultiple quote feedsExchange feeds
ChartsTradingView embedsBuilt inBuilt inBuilt in
Price alertsYes, via Inngest cronNoNoYes
Holdings and P&LNo, watchlist onlyYesYesYes
Setup effortNode, MongoDB, one API keyDocker ComposeInstallerAccount 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.

What to watch · 2026
  • An .env.example and a release. Both are missing today and both would cut first-run friction in half. The check-env.mjs script 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.

Primary sources

Original analysis by GenZTech. Tool documentation: Open-Dev-Society/OpenStock on GitHub.