老骥伏枥,志在千里。烈士暮年,壮心不已——曹操

https://github.com/Open-Dev-Society/OpenStock

OpenStock:当股市工具不再高冷,开源终于把金融世界的门轻轻推开了

如果你也曾在寻找一款股票市场工具时,被复杂的界面劝退,被昂贵的订阅吓住,被“专业人士专属”的气场挡在门外,那么 OpenStock 大概会让你眼前一亮。

它像一个不爱摆架子的朋友,站在市场数据与普通用户之间,主动伸出手说:别怕,我带你进去看看。

OpenStock 是一个开源的股票市场应用,它把原本属于高价平台的体验,搬到了一个公开、透明、人人可参与的空间里。你可以查看实时价格,设置个性化提醒,探索详细的公司信息,还能在一个现代化、顺手、漂亮的界面里完成这些事。更重要的是,它不是围绕“如何收费”设计出来的,而是围绕“如何让更多人平等使用”诞生的。

这不是一款想把用户困在付费墙里的产品。

它更像是一个有理想的建设者,认真地说着一句话:市场信息不该只属于少数人,优秀工具也不该天然昂贵。

一个项目的气质,往往藏在它的第一句话里

OpenStock 的仓库描述很直接,也很有力量:

OpenStock is an open-source alternative to expensive market platforms. Track real-time prices, set personalized alerts, and explore detailed company insights — built openly, for everyone, forever free.

翻成更有温度的话,就是:

OpenStock 想做昂贵市场平台的开源替代者。它希望你能轻松追踪价格,设置属于自己的提醒,查看详尽的公司信息,而且这一切都建立在公开构建、面向所有人、永久免费这样的信念之上。

这句话很像是 OpenStock 的自我介绍。它没有夸张地许诺“颠覆行业”,也没有故作神秘地堆砌术语。它只是坦率地把自己的目标讲清楚:让更多人拥有本该平等获得的市场工具体验。

它不是券商,它更像一位安静但可靠的市场向导

README 里有一句很重要的话:OpenStock 是社区构建的项目,它不是券商。市场数据可能因为数据提供方规则和配置而存在延迟,这里的内容也不构成任何投资建议。

这一点非常值得强调,但不是为了“降调”,而是为了看清它真正的位置。

OpenStock 不负责替你下单,不扮演“投资导师”,也不试图把用户推向情绪化的交易行为。它更像一个克制、理性的陪伴者,负责把信息整理给你,把行情摆在你面前,把观察市场这件事变得更轻盈、更顺滑、更容易开始。

它不替你做决定,但它努力让你拥有更好的信息入口。

它最动人的地方,不只是功能,而是立场

如果说许多项目先讲“我能做什么”,那么 OpenStock 还有一个更珍贵的层次:它会先告诉你“我为什么而做”。

在 README 的 Open Dev Society Manifesto 部分,项目背后的理念非常鲜明。它谈到知识被付费墙遮蔽,工具被订阅锁住,信息被偏见扭曲,新人常常被告知“不够格”。

然后它给出了一种更理想主义,也更有人情味的回答:

  • 技术应该属于每一个人
  • 知识应该开放、自由、可访问
  • 社区应该欢迎新手,而不是设置门槛
  • 资源应该建立在信任之上,而不是利润优先

这段宣言让 OpenStock 不再只是一个看盘工具,而像一位带着信念上路的同行者。

它仿佛在说:如果你曾经因为看不懂、买不起、接触不到而被挡在门外,那这一次,门为你开着。

这种气质,其实很难得。因为它让一个技术项目不只是“能用”,而是“有态度”;不只是“上线了”,而是“在认真地为某些人争取机会”。

OpenStock 到底能做什么

如果只看一句话,OpenStock 是现代化的股票市场应用。

但如果展开看,它做的事情比“看价格”丰富得多,而且这些功能组织得很完整,能让用户从首次进入到持续使用,都有较顺滑的体验。

1. 认证系统,让每位用户都拥有自己的空间

OpenStock 支持基于邮箱和密码的身份认证,使用 Better Auth 搭配 MongoDB 适配器来完成用户管理。项目还通过 Next.js 的中间件保护受限路由。

这意味着它不是一个“纯展示型页面”,而是一个能记住你、服务你、为你建立个性化体验的真实应用。

它会认识你,也会记住你的使用轨迹。

2. 股票搜索和命令面板,让查找这件事更像对话而不是折腾

OpenStock 提供快速股票搜索能力,背后由 Finnhub 提供支持。用户空闲时可以看到热门股票,搜索过程带有防抖处理,整体体验更轻快。

同时,它还支持 Command + K 或 Ctrl + K 快捷操作。这种设计很像是在给用户一个秘密通道:当你熟悉它之后,很多动作都不再需要层层点击,而是像跟一个懂你习惯的助手直接沟通。

一个好的工具,往往知道什么时候该少说话、少打扰、少增加操作成本。OpenStock 在这方面做得很有现代产品感。

3. Watchlist,自选股不再只是功能,而像是你的观察清单

每位用户都可以维护自己的 Watchlist,数据会存储在 MongoDB 中,并确保每个用户的股票代码唯一。

这看上去是个常见功能,但真正重要的是,它让 OpenStock 从“公共信息看板”变成了“个人市场工作台”。

你关心什么,它就陪你盯着什么。

你不是面对一片混乱的大海,而是先拥有了自己的航线图。

4. 股票详情页,把碎片信息整理成更完整的观察窗口

OpenStock 的股票详情页是它非常有吸引力的一部分。它集成了 TradingView 的符号信息、K 线图、高级图表、基线图和技术面相关组件,还能展示公司简介和财务相关窗口。

这意味着你不是只看到一个冷冰冰的价格数字,而是能在更完整的上下文里理解一家公司。

价格只是表情,信息才是性格。

而 OpenStock 愿意把这些性格线索认真地摆在你面前。

5. 情绪洞察,把市场的喧闹也纳入观察

项目还支持可选的跨来源情绪分析,覆盖 Reddit、X.com、新闻以及 Polymarket 等来源。

这很有意思。因为市场从来不是只由财报、指标和图表组成,它也由情绪、预期、讨论热度和群体心理共同塑造。OpenStock 没有把这些声音粗暴地当作“噪音”排除,而是谨慎地把它们纳入观察维度。

像是一个懂市场脾气的人,轻声提醒你:

除了数字,别忘了听听风向。

6. 市场总览,让大盘不再抽象

Heatmap、报价、头条故事等能力,也通过 TradingView 小组件被整合到应用里。

于是市场不再只是一个个分散的代码,而开始呈现出整体氛围。涨跌不再只是点状事件,而更像是一整张会呼吸的地图。

你在这里看到的不是孤立的波动,而是一个更有场景感的市场世界。

7. 个性化 onboarding,让产品先了解你,再陪伴你

OpenStock 会收集用户的国家、投资目标、风险承受能力、偏好行业等信息,用于个性化体验构建。

这一步的意义不在于“多收几个表单字段”,而在于它努力让后续内容更贴近用户本身。一个刚入门的新手,和一个目标明确的长期投资者,本来就不该被同一种信息方式对待。

OpenStock 在这一点上更像一个耐心的顾问:先认识你,再陪你继续往前走。

8. 自动化与邮件能力,让服务不止停留在打开页面的那一刻

项目使用 Inngest 处理事件、定时任务和 AI 推理能力,还接入了 Nodemailer 用于邮件通信。

其中包括:

  • AI 个性化欢迎邮件
  • 基于用户 watchlist 的每日新闻摘要邮件

这里最动人的地方在于,OpenStock 并没有满足于“用户登录了就算完成服务”。它还想在用户离开页面之后,继续以一种不打扰但有价值的方式陪伴用户。

它像个懂分寸的朋友,不会一天到晚喋喋不休,但会在合适的时候,把你真正关心的消息递过来。

9. 精致界面与暗色主题,让信息密度和视觉舒适可以和平相处

OpenStock 使用 shadcn/ui、Radix UI primitives 和 Tailwind CSS v4 构建界面,默认采用暗色主题。

这套技术选择背后对应的是一种现代前端审美:简洁、清晰、响应自然、组件统一。对于金融类产品来说,界面设计不是装饰,而是理解效率的一部分。

一个混乱的界面会放大焦虑,一个清晰的界面会降低认知成本。

OpenStock 的界面风格明显站在后者这边。

它的技术栈,有一种“现代开源应用完整体”的味道

OpenStock 的技术栈很清晰,也很有代表性,几乎是一套面向现代 Web 应用的完整组合拳。

核心部分包括:

  • Next.js 15
  • React 19
  • TypeScript
  • Tailwind CSS v4
  • shadcn/ui
  • Radix UI
  • Lucide Icons

认证与数据层包括:

  • Better Auth
  • MongoDB
  • Mongoose
  • Finnhub
  • TradingView

自动化与通信部分包括:

  • Inngest
  • Nodemailer
  • next-themes
  • cmdk
  • react-hook-form

如果把这些技术拟人化来看,OpenStock 像是组建了一支很协调的团队:

  • Next.js 负责搭建舞台和流程秩序
  • TypeScript 像严谨的项目经理,努力减少混乱
  • Tailwind CSS 和 shadcn/ui 像审美在线的设计搭档
  • MongoDB 负责稳稳收纳数据
  • Finnhub 和 TradingView 像消息灵通的市场情报员
  • Better Auth 守在门口,认真辨认每一位来访者
  • Inngest 则像幕后调度员,让定时任务和自动流程默默运转
  • Nodemailer 像一个负责送信的邮差,准时把该送达的内容递到用户手里

它们组合在一起,让 OpenStock 不是某个单点功能的展示,而是一个可落地、可运行、可扩展、可协作的完整产品。

从项目结构里,能看出它很认真地在长大

OpenStock 的目录结构很规整,应用入口、组件、数据库、业务动作、自动化逻辑、邮件模板、脚本和类型定义都被清楚拆分。

这类结构传递出一种很重要的信息:它不是一个“为了演示而存在”的一次性仓库,而是一个在认真朝着长期维护方向生长的项目。

你能看到:

  • app/ 负责页面与路由组织
  • components/ 收纳通用 UI 和表单能力
  • database/ 处理模型和数据库连接
  • lib/actions/ 存放服务端动作
  • lib/inngest/ 管理工作流、函数和提示词
  • lib/nodemailer/ 处理邮件发送和模板
  • scripts/ 提供数据库测试脚本

这像是一间逐渐成型的工作室,每样工具都被放到了它该在的位置。一个项目愿意整理自己的抽屉,通常也意味着它愿意为后来者留下清晰的路径。

Quick Start 很友好,几步就能把它请到本地

如果你想亲自把 OpenStock 跑起来,它在 README 里提供了相当完整的快速启动说明。整个过程并不绕,甚至可以说很照顾开发者体验。

环境前提

你需要准备:

  • Node.js 20+
  • pnpm 或 npm
  • MongoDB 连接字符串
  • Finnhub API Key
  • Gmail 账号用于邮件功能,或者自行调整 Nodemailer 的传输配置
  • 可选的 Gemini API Key,用于 AI 生成欢迎内容

克隆并安装依赖

1
2
3
4
5
6
git clone https://github.com/Open-Dev-Society/OpenStock.git
cd OpenStock

pnpm install
# 或
npm install

这一步像是向项目打招呼。仓库落地,本地环境准备好,OpenStock 就开始在你的机器上安顿行李了。

配置环境变量

项目要求在根目录创建 .env 文件。README 给出了相当完整的变量示例,涵盖数据库、认证、Finnhub、AI、Inngest 和邮件配置。

一个典型示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
NODE_ENV=development

MONGODB_URI=mongodb+srv://<user>:<pass>@<cluster>/<db>?retryWrites=true&w=majority

BETTER_AUTH_SECRET=your_better_auth_secret
BETTER_AUTH_URL=http://localhost:3000

NEXT_PUBLIC_FINNHUB_API_KEY=your_finnhub_key
FINNHUB_BASE_URL=https://finnhub.io/api/v1

ADANOS_API_KEY=your_adanos_api_key

GEMINI_API_KEY=your_gemini_api_key

INNGEST_SIGNING_KEY=your_inngest_signing_key

NODEMAILER_EMAIL=youraddress@gmail.com
NODEMAILER_PASSWORD=your_gmail_app_password

这些变量像是 OpenStock 出门前要带上的证件、钥匙和通讯录。少了谁,它都可能在某个环节卡住;带齐之后,它就能流畅地开始工作。

测试数据库连接

1
2
3
pnpm test:db
# 或
npm run test:db

这是个很实用的小步骤。很多项目喜欢让你直接启动,出了问题再自己排查;OpenStock 则贴心地给了一个数据库连接验证脚本,相当于先帮你检查门有没有锁好、电有没有通上。

启动开发环境

1
2
3
pnpm dev
# 或
npm run dev

启动后访问:

1
http://localhost:3000

一个完整的市场应用,就会在你的本地浏览器里“醒过来”。

本地运行 Inngest

如果你想体验工作流、定时任务和 AI 相关逻辑,还可以额外启动 Inngest:

1
npx inngest-cli@latest dev

这一步像是唤醒 OpenStock 的后台大脑。页面可见的部分是它的外在,自动化工作流则是它不动声色的神经系统。

构建生产版本

1
2
3
pnpm build && pnpm start
# 或
npm run build && npm start

当一切准备妥当,OpenStock 也可以从开发状态走向更正式的运行状态。像一位在排练厅里打磨很久的演员,终于走上真正的舞台。

Docker 支持也准备好了,部署体验更省心

对于喜欢容器化方案的开发者来说,OpenStock 也给出了 Docker Compose 的支持。

README 中说明,项目可以通过 Docker Compose 同时运行应用和 MongoDB。你只需要准备好 .env,并使用本地连接字符串,例如:

1
MONGODB_URI=mongodb://root:example@mongodb:27017/openstock?authSource=admin

启动命令如下:

1
docker compose up -d mongodb && docker compose up -d --build

这一步的好处在于,它让环境准备变得更加一致。MongoDB 被一起拉起,数据卷负责持久化,服务依赖关系也更加明确。对于团队协作或本地快速试跑来说,这种体验非常友好。

你可以把 Docker 理解成 OpenStock 的移动小屋。无论换到哪台机器,只要基础条件满足,它都能比较稳定地重新安家。

数据与集成,不是简单堆功能,而是各司其职

OpenStock 在集成层面做得很完整,而且每个外部服务的职责都比较清楚。

Finnhub

负责股票搜索、公司资料和市场新闻,是市场信息的重要来源之一。

TradingView

负责图表、热力图、报价和时间线等可视化组件,让数据不仅可得,而且可读。

Better Auth + MongoDB

负责用户认证、会话验证和持久化存储,支撑个性化能力。

Inngest

负责事件和定时任务,包括:

  • app/user.created 触发 AI 个性化欢迎邮件
  • 0 12 * * * 的每日新闻摘要任务

Nodemailer

负责邮件发送,让欢迎内容和新闻摘要真正抵达用户。

Adanos

用于可选的情绪分析卡片,帮助用户从 Reddit、X.com、新闻和 Polymarket 等来源获得更结构化的情绪快照。

这套集成关系很像一支分工明确的小团队。每个人都不是来“抢戏”的,而是认真负责自己那一段工作。最终呈现出来的体验,会让用户感觉一切都衔接得很顺,而不是东拼西凑。

它对开发者也很友好,脚本和工具链都很实在

OpenStock 提供的脚本包括:

  • dev:Next.js 开发服务器
  • build:生产构建
  • start:生产启动
  • lint:ESLint 检查
  • test:db:数据库连接测试

看起来普通,但恰恰是这些“普通的细节”,决定了一个项目是否容易参与、容易维护、容易协作。

此外,它还使用了 TypeScript strict mode,采用 Tailwind CSS v4、shadcn/ui、Radix primitives、cmdk、next-themes 和 lucide-react 等工具,说明项目在开发体验和工程质量上也有比较现代的考虑。

它不是只想“做出来”,还想“做舒服”。

这个项目欢迎贡献,而且欢迎得很真诚

README 中有一句特别暖的话:

You belong here.

无论你是学生、自学开发者,还是经验丰富的工程师,都欢迎参与贡献。

这不是一句客套话,因为后面还有很清晰的社区姿态:

  • 可以开 issue 讨论想法和 bug
  • 可以寻找 good first issuehelp wanted
  • PR 尽量聚焦
  • UI 改动建议加截图
  • 对新人保持善意,拒绝 gatekeeping,这就是 ODS 的方式

很多开源项目说“欢迎贡献”,但语气里总有一点门槛感。OpenStock 的不同之处在于,它似乎真的把“新手也属于这里”当成了社区的一部分,而不是宣传文案里的礼貌性句子。

它像一张留着空位的长桌,不是为了显示热闹,而是真的在等更多人坐下来。

它的许可证,也体现了对开放的认真

OpenStock 采用 AGPL-3.0 许可证。

这意味着项目不仅开源,而且对于修改、再分发、部署为网络服务等场景,也要求继续以相同许可证开放源代码。

这不是一种“控制欲”,反而更像是一种价值守护。它在说:既然我们选择公开构建、为所有人免费,那就希望这份开放不要在传播过程中被悄悄收回。

项目想保护的,其实不是自己的垄断,而是开放本身。

它还记得感谢,也记得来路

README 的致谢部分提到了 Finnhub、TradingView、shadcn/ui、Radix UI、Tailwind CSS、Next.js 社区、Inngest、Better Auth,以及所有贡献者。

它还特别感谢了 Adrian Hajdin 和 JavaScript Mastery 的相关教程对项目建设的帮助。

一个会认真感谢他人启发的项目,往往也更懂得开源世界真正珍贵的东西:不是“我比谁更强”,而是“我站在许多人的肩膀上,也愿意继续搭肩给后来的人”。

这份谦逊,其实很迷人。

为什么我会觉得 OpenStock 值得写一篇长文

因为它不只是一个“股票应用”。

它同时是:

  • 一个现代 Web 技术栈的开源实践样本
  • 一个金融信息工具平权的尝试
  • 一个对新手友好的社区姿态展示
  • 一个把产品体验、自动化能力、个性化服务组合在一起的完整项目
  • 一个带有明确价值观的开源作品

很多项目的 README 只是在介绍功能,OpenStock 的 README 更像在介绍一个正在成长中的世界观。

它告诉你,技术不必只服务于付费能力最强的人;工具不必只朝着商业围墙前进;一个社区也可以在追求质量的同时,保持善意与开放。

如果把 OpenStock 拟人化,它不像华尔街高楼里西装笔挺、拒人千里的顾问,更像一位穿着连帽衫、抱着笔记本、眼睛发亮的年轻建造者。他不准备把市场变得神秘,他想做的,是把信息整理好、把门打开、把路铺平,然后回头招呼一句:

来吧,一起看,一起学,一起做点真正公开的东西。

结语

在一个工具越来越容易变成订阅,在信息越来越容易被分层、被包装、被售卖的时代,OpenStock 的存在像是一种朴素但坚定的提醒:

总有人还在认真做开放、免费、面向所有人的产品。

它不喧哗,不摆谱,不试图用浮夸口号掩盖现实,而是老老实实把搜索、图表、认证、提醒、邮件、自动化、个性化体验一块块搭起来,再把整个项目放到开源世界里,邀请所有人一起完善。

这份诚意,本身就值得被看见。

如果你正在寻找一个值得体验、学习、关注甚至参与贡献的开源项目,那么 OpenStock 很适合进入你的视野。它也许不是那个最张扬的名字,但它像一粒认真发芽的种子,已经在告诉大家:市场工具的未来,不一定只能昂贵,也可以开放;不一定只能高门槛,也可以人人可及;不一定只能由少数公司定义,也可以由社区一起建设。

而这,或许正是 OpenStock 最动人的地方。

它把复杂的市场世界,朝普通人多走近了一步。