Contents

MōBrowser 2.0.0

Today we’re announcing MōBrowser 2.0.0 — a major release that makes it possible to build native cross‑platform desktop apps with a TypeScript-first stack, while still keeping the option to extend your app with native code when you need it.

MōBrowser 2.0.0

In MōBrowser 1.x.x, our core idea was to help C++ teams build modern desktop UIs faster by combining two worlds: C++ for business logic and web technologies (HTML, CSS, JavaScript) for the user interface. Web UI frameworks make it possible to ship polished interfaces quickly, and MōBrowser connected that UI layer to native desktop capabilities.

In practice, this approach often meant maintaining two stacks in one product: C++ for the backend and web technologies for the frontend. That typically requires at least two specialized skill sets on the team, which can increase cost and slow down iteration.

We asked ourselves a simple question: if the developers already need web technologies for the UI, why not let them build both the UI and the application logic on a single stack — and use native code only for the parts that truly require it?

TypeScript & Node.js 

Starting with 2.0.0, MōBrowser lets you build native desktop applications using web technologies only, with TypeScript as the primary language.

For real-world desktop apps, business logic usually needs access to the file system, the network, and the ability to run system commands. That’s why MōBrowser 2.0.0 includes a built-in Node.js runtime.

You can write the entire application logic in TypeScript and call Node.js APIs when needed:

import { app } from '@mobrowser/api';
import * as process from "node:process";

// Create a new browser window.
const win = app.createWindow()
win.setWindowTitlebarVisible(process.platform === 'win32')
win.centerWindow()
win.show()

// Load and display a web page.
win.browser.loadUrl('https://example.com')

Process model 

MōBrowser still uses Chromium under the hood and follows its multi-process architecture.

The main process runs the Node.js runtime and executes your application code written in TypeScript. It has access to OS capabilities such as file system, networking, clipboard, and other system features. This is where you implement your application logic, create windows, show native dialogs, and integrate with the operating system.

The renderer process loads and runs your frontend UI. It runs in an isolated environment without direct access to the file system. This isolation is important for security: your UI can include untrusted or remotely loaded content, and limiting renderer privileges reduces the impact of XSS and supply-chain attacks.

Inter-process communication (IPC) 

Communication between the renderer and the main process is done via IPC based on Protocol Buffers (Protobuf) services and messages.

You declare the services and message types in a .proto file:

syntax = "proto3";

import "google/protobuf/wrappers.proto";

// Message definition.
message Person {
  string name = 1;
}

// Service definition.
service GreetService {
  rpc SayHello(Person) returns (google.protobuf.StringValue);
}

MōBrowser generates TypeScript code. In the main process, you implement the services and register them:

import { ipc } from '@mobrowser/api';
import { Person } from './gen/greet';
import { GreetService } from './gen/ipc_service';

// Handle the IPC calls from the renderer process.
ipc.registerService(GreetService({
  async SayHello(person: Person) {
    return { value: `Hello, ${person.name}!` };
  },
}))

In the renderer process, you call the service methods:

import { ipc } from "./gen/ipc";

ipc.greet.SayHello({ name: 'John' }).then((message) =>
  console.log(message.value) // Hello, John!
)

Project scaffolding tool 

Project generation works the same way as in 1.x.x. Using the official project scaffolding tool, you can create a new project by answering a few questions: choose a frontend framework (React, Vue, Vanilla, None), a UI component library (Shadcn, Material-UI, Ant Design, Quasar), and whether your frontend uses TypeScript or JavaScript.

In version 2.0.0, the scaffolding tool can also set up an optional native C++ module. If you enable it, the tool adds everything needed to build and ship a native module and includes an example that shows how to call the module from TypeScript.

Native C++ module 

Operating systems expose a large set of system capabilities. If your application needs a specific OS feature that is not available through the framework API, you can extend your app with a native module.

In a native module, you can call OS APIs using C++. The module is loaded by your application automatically, and you can call it directly from TypeScript. Communication between C++ and TypeScript is based on Protobuf.

It works in the same way as IPC between the renderer and main processes. You define the messages and services in a .proto file, generate the code, and implement the required services in C++ as shown below:

#include <iostream>

#include "rpc.h"
#include "gen/greet.rpc.h"

using google::protobuf::StringValue;
using mo::rpc::Callback;

class GreetServiceImpl : public GreetService {
 public:
  void SayHello(const Person* person,
                Callback<StringValue> done) override {
    StringValue response;
    response.set_value("Hello, " + person->name() + "!");
    std::move(done).Complete(response);
  }
};

void launch() {
  mo::rpc::RegisterService(new GreetServiceImpl());
}

In the main process, you import the generated code and call the service using TypeScript:

import { app } from '@mobrowser/api';
import { native } from './gen/native';

const response = await native.greet.SayHello({ name: 'John Doe' })
console.log(response.value) // Hello, John Doe!

Source code protection 

Now that application logic is written in TypeScript, protecting your source code becomes important. TypeScript is not compiled into a native binary, so it can be easier to extract and inspect from a shipped application.

In MōBrowser, we address this with a built-in mechanism to protect and encode your application source code — both backend and frontend. In addition, application assets such as CSS files and images can also be protected.

If certain assets do not need protection, you can place them in a dedicated location so they will be shipped as-is.

Friendly to AI coding agents 

We ship the framework API as TypeScript declaration files (.d.ts) that you import into your application. This makes the API discoverable in IDEs and provides strong autocomplete and inline documentation.

In the declaration file, we provide detailed documentation and usage examples for each API. As a result, AI coding agents can reliably find the API specification and usage examples directly in the project context, making it easier to generate correct code without searching external sources.

MōBrowser vs Electron vs Tauri 

A common question is how MōBrowser compares to frameworks like Electron and Tauri. The table below highlights the differences.

FeatureMoBrowserElectronTauri
Project scaffolding tool✅ Yes. Official scaffolding via create-mobrowser-app.⚠️ Available via separate tooling (e.g. Electron Forge).✅ Yes. Official scaffolding via create-tauri-app.
Single codebase and language✅ Yes. TypeScript for both frontend and backend.✅ Yes. JavaScript for both frontend and backend.❌ No. JavaScript for frontent. Rust for backend.
Source code protection✅ Built-in encryption and protection of source code and resources for both frontend and backend.❌ No built-in source code and resources protection (ASAR is packaging, not protection).⚠️ No built-in protection of source code and resources for the frontend.
Enterprise support with SLAs✅ Yes. Response within 4 business hours.❌ No. Community support only.❌ No. Community support only.
Consistent rendering across different platforms✅ Yes. Chromium engine on all platforms.✅ Yes. Chromium engine on all platforms.❌ No. Rendering differs across platforms due to the use of different web engines.
Node.js runtime✅ Full Node.js runtime support.✅ Full Node.js runtime support.❌ No built-in Node.js runtime.
Navite APIs access✅ Native C++/Rust modules for platform API access and compute‑intensive tasks.✅ Native Node add-ons (C/C++).✅ Native extensions typically implemented via Rust/plugins.

Free for non-commercial use 

Starting with version 2.0.0, MōBrowser is available free of charge for non-commercial use. This option allows thousands of developers to build desktop applications for personal projects, education, academic research, and other non-commercial purposes using the web technologies they love.

What’s next 

We plan to continue expanding the framework API by adding capabilities that are commonly needed in modern desktop apps, such as desktop notifications, launch at login, database access (SQLite and IndexedDB), application preferences, system preferences, accessibility access, microphone and webcam access, screens, native images, and more.

In addition to C++ support in native modules, we plan to add Rust support.

In upcoming releases, we will add support for publishing applications to the Mac App Store and Microsoft Store.

If you have any questions or feature requests, please feel free to contact us.