ERPFit không bán phần mềm đóng gói. Chúng tôi xây dựng giải pháp cho từng doanh nghiệp, rồi chuyển giao để họ tự vận hành. Điều đó có nghĩa là stack công nghệ phải đáp ứng được hai yêu cầu: chúng tôi phát triển nhanh, và khách hàng không bị phụ thuộc vào bất kỳ ai.
Mã nguồn mở giải quyết cả hai. Không có license fee, không bị khóa vendor, và khi cần — bất kỳ lập trình viên nào cũng có thể đọc code, sửa, hoặc thay thế.
Runtime: Bun
Trước Bun, chúng tôi dùng Node.js. Chuyển sang Bun không phải vì hype — mà vì ba lý do thực tế:
- Startup nhanh hơn đáng kể. Các script tự động hóa chạy hàng ngày (health check, backup verify, data sync) cần khởi động trong mili-giây, không phải giây. Bun khởi động nhanh hơn Node.js khoảng 4 lần trong các script nhỏ.
- TypeScript native. Không cần
tsc, không cầnts-node, không cầntsx. Viết.ts, chạy trực tiếp. Giảm đáng kể ma sát trong development. - Built-in test runner, bundler, package manager. Ít công cụ hơn = ít thứ phải maintain. Trong một team nhỏ, điều này quan trọng.
Bun không hoàn hảo. Một số package npm có native binding vẫn gặp vấn đề. Nhưng với stack TypeScript-first, chúng tôi hiếm khi cần native modules. Trade-off xứng đáng.
Web framework: Hono
Hono là web framework chạy trên mọi runtime — Bun, Deno, Cloudflare Workers, Node.js. Chúng tôi chọn Hono vì:
- Nhẹ. Bundle size không đáng kể so với Express hay Fastify. Quan trọng khi chạy trên VPS nhỏ.
- API quen thuộc. Nếu bạn biết Express, bạn biết Hono. Middleware pattern giống nhau.
- JSX support. Hono có JSX renderer riêng — không cần React. Website erpfit.com chạy Hono JSX, server-rendered, không có client-side hydration. Nhanh, đơn giản.
- Runtime-agnostic. Nếu một ngày Bun không còn phù hợp, chuyển sang Deno hoặc Node.js chỉ cần đổi adapter.
Hono kết hợp với tRPC cho các API cần type safety end-to-end — client gọi API có autocompletion, server validate tự động. Pattern này hiệu quả với TypeScript monorepo.
Database: PostgreSQL (và MariaDB khi cần)
PostgreSQL là lựa chọn mặc định cho mọi dự án mới. Lý do đơn giản: nó làm được gần như mọi thứ — relational, JSON, full-text search, PostGIS cho geolocation, tốt ở scale nhỏ lẫn lớn.
Widget platform dùng PostgreSQL + PostGIS cho store locator — tính khoảng cách, tìm cửa hàng gần nhất. Không cần thêm service riêng cho geo queries.
MariaDB vẫn được dùng khi cần — ERPNext chạy trên MariaDB, WordPress dùng MySQL. Chúng tôi không dogmatic về database — dùng cái phù hợp nhất cho từng bài toán.
Infrastructure: Cloudflare + Linux + Docker
Cloudflare miễn phí cho hầu hết những gì chúng tôi cần: DNS, CDN, SSL, DDoS protection, và Cloudflare Tunnel cho các service chạy on-premise mà không cần public IP.
Server chạy trên VPS (Vultr, Hetzner) và Proxmox on-premise. Docker + Coolify để quản lý containers, Traefik làm reverse proxy. Tất cả đều open source.
Sao lưu hàng ngày, lưu trữ 30 ngày, bản sao offsite qua SFTP. Giám sát bằng Uptime Kuma — 19+ service endpoints, cảnh báo qua Telegram trong vài phút khi có sự cố.
Tại sao không dùng cloud managed services?
AWS, GCP, Azure đều có managed database, managed Kubernetes, managed everything. Nhưng cho doanh nghiệp nhỏ Việt Nam:
- Chi phí không tương xứng. Một RDS instance nhỏ nhất đã tốn nhiều hơn cả VPS chạy PostgreSQL + 5 app containers.
- Vendor lock-in thực sự. Lambda, DynamoDB, Cloud Functions — code viết cho cloud cụ thể khó chuyển đi. Chúng tôi muốn khách hàng tự do.
- Đơn giản hơn cho quy mô SME. 2-3 VPS, Docker Compose, Traefik — đủ cho 99% nhu cầu. Kubernetes là overkill khi bạn chưa có 10 microservices.
Điều này không có nghĩa cloud managed services sai — chỉ là không phù hợp cho đối tượng khách hàng của chúng tôi.
Nguyên tắc chọn công nghệ
Sau vài năm thử nghiệm, chúng tôi rút ra được vài nguyên tắc:
- Ưu tiên boring technology. PostgreSQL boring hơn MongoDB. Linux boring hơn serverless. Boring có nghĩa là ổn định, có documentation tốt, dễ tìm người hỗ trợ.
- Ít tool hơn = ít vấn đề hơn. Mỗi tool thêm vào stack là thêm một thứ phải update, monitor, debug. Bun thay thế Node + tsc + jest + npm bằng một tool duy nhất.
- Open source trước, trả phí khi cần. Dùng Mautic thay Mailchimp, Uptime Kuma thay Datadog, Coolify thay Vercel. Không phải lúc nào open source cũng tốt hơn — nhưng nó luôn là điểm khởi đầu đúng.
- Chuyển giao được. Stack phải là thứ lập trình viên khác có thể tiếp nhận. TypeScript + PostgreSQL + Docker — hầu như ai cũng biết. Đó là lợi thế lớn nhất.
Stack không quan trọng bằng cách bạn dùng nó. Nhưng chọn đúng stack từ đầu tiết kiệm rất nhiều thời gian và tiền bạc về sau — đặc biệt cho doanh nghiệp nhỏ, nơi mỗi quyết định công nghệ đều ảnh hưởng trực tiếp đến chi phí vận hành.