How Manaby Was Built: A Technical Deep Dive
The technologies, architecture decisions, and tools that power Manaby browser.
Table of Contents
- The Foundation: Electron
- The UI: React 19 + TypeScript
- State Management: Zustand
- Database: Better SQLite3 + Drizzle ORM
- Build System: Electron Forge + Webpack
- Ad Blocking: Ghostery
- The Architecture
- Split View System
- Password Manager
- Themes
- What’s Next
Building a browser from scratch sounds insane. And it kind of is. But with the right tools, it becomes possible. Here’s everything that powers Manaby under the hood.
The Foundation: Electron
Manaby is built on Electron, the same technology behind VS Code, Slack, and Discord. Electron lets me use web technologies (HTML, CSS, JavaScript) while having full access to native APIs.
Why Electron? Because it’s battle-tested. Chromium handles the web rendering—I don’t need to reinvent that wheel. What I needed was control over the browser chrome: the tabs, the toolbar, the split views. Electron gives me that.
Version: Electron 39 with Chromium 134.
The UI: React 19 + TypeScript
The entire interface is built with React 19. Every tab bar, every button, every panel is a React component. TypeScript keeps everything type-safe, which matters when you’re dealing with complex state.
Why React and not something lighter? Because I know it well, and the ecosystem is mature. When I need a hook or a pattern, I don’t have to figure it out—it’s already solved.
State Management: Zustand
For global state, I chose Zustand over Redux or MobX. It’s simple, fast, and doesn’t require boilerplate.
// Example: SearchBar store
const useSearchBarStore = create<SearchBarState>((set) => ({
mode: 'search',
query: '',
setQuery: (query) => set({ query }),
setMode: (mode) => set({ mode }),
}));
Each feature has its own store: tabs, downloads, passwords, settings. They’re isolated, which makes debugging straightforward.
Database: Better SQLite3 + Drizzle ORM
All local data (passwords, history, session state) is stored in SQLite via better-sqlite3. For the ORM layer, I use Drizzle—it’s type-safe and generates efficient SQL.
Why SQLite? It’s embedded, fast, and doesn’t need a server. Perfect for a desktop app. The database file lives locally, your data never leaves your machine.
Build System: Electron Forge + Webpack
Electron Forge handles packaging and distribution. It creates DMG files for macOS, NSIS installers for Windows, and AppImage/DEB/RPM for Linux.
The code is bundled with Webpack. The main process and renderer process have separate configurations. Hot reload works in development, which makes iteration fast.
Ad Blocking: Ghostery
Instead of building my own ad blocker, I integrated Ghostery’s adblocker-electron library. It’s the same engine that powers the Ghostery browser extension.
It blocks:
- Ads
- Trackers
- Fingerprinting scripts
You can whitelist sites when you want to support them.
The Architecture
Manaby follows Electron’s multi-process model:
Main Process
- Window management
- Session handling
- IPC communication hub
- Native API access (file system, clipboard, etc.)
Renderer Process
- React UI
- Tab content rendering
- Local state (Zustand)
- User interactions
Preload Scripts
- Bridge between main and renderer
- Expose safe APIs via context bridge
- Handle IPC calls
┌─────────────────────────────────────────┐
│ Main Process │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Windows │ │ Sessions│ │ IPC │ │
│ └─────────┘ └─────────┘ └─────────┘ │
└───────────────────┬─────────────────────┘
│
┌───────────┼───────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Renderer 1│ │ Renderer 2│ │ Renderer N│
│ (Tab) │ │ (Tab) │ │ (Tab) │
└───────────┘ └───────────┘ └───────────┘
Split View System
One of the most complex features. The split view manager tracks:
- Up to 4 groups per window
- Orientation (vertical/horizontal)
- Ratios between groups
- Focus state per group
- Tab drag-and-drop between groups
The logic lives in split-view-manager.ts—about 500 lines of carefully orchestrated state management.
Password Manager
Passwords are encrypted with a master password before being stored. The autofill system injects credentials into login forms using a preload script.
User enters password
↓
Encrypt with master key
↓
Store in SQLite
↓
On login page detected
↓
Decrypt and autofill
Themes
Nine themes are available, implemented as CSS custom properties:
- Dark (default)
- Light
- Nord
- Dracula
- Tokyo Night
- Catppuccin
- Monokai
- Ayu
- Solarized
Switching themes updates the variables in real-time. No page reload needed.
What’s Next
The architecture is solid, but there’s always more to build:
- Extension support (Chrome extensions compatibility)
- Better tab grouping
- Performance optimizations
- Mobile version (someday)
If you want to see the code in action, download Manaby and take it for a spin. The best way to understand how it works is to use it.