Next generation · launching end of 2026 · Chromium · Android · Lua 5.4

The browser that
runs your code.

  • 200K open it every day
  • 67% come back

The household desktop-class browser in Indonesia, Vietnam, Brazil, India and the Philippines.

Lemur is Chromium with a Lua runtime living inside the browser process. Not an extension API — the whole thing: tabs, network, the DevTools Protocol, the native toolbar, every renderer process. Drop a .lua file in, restart, and the browser is yours.

  • 6 years shipping
  • 5M geeks worldwide
  • 40+ lemurx.* modules
  • ∞ escape hatches
  • Chrome extensions
  • Edge add-ons
  • Userscripts
  • λ Lua
Lemur browser logo
files/lua/00_hello.lua

Why

Extensions ask permission.
Scripts just do it.

Browser extensions live in a sandbox on the far side of an API designed to keep them out. A Lemur script is code running in the browser process, next to Chromium's own. Same privileges as the browser, because it is the browser.

Can you…
Chrome extension
Lemur script
Rewrite response bodies on the fly
Headers & redirects only
net.addRule{ replaceBody = … }
Put a button on the real toolbar, or replace the bottom bar
Popups and side panels
ui.render("toolbar.end", …)
Dump, restyle or tear out any native View
—
ui.dump() · ui.style() · ui.replace()
Full Chrome DevTools Protocol on a phone
Desktop only, one domain at a time
cdp.send(tab, "Any.method", …)
Fetch anything, no CORS, no host permissions
Declare every host up front
http.fetch(url)
Read and write Chromium's own prefs, site permissions and feature flags
—
prefs.set · perm.set · features.enabled
Run Lua inside every renderer, on real DOM handles
—
page · dom_document · send-request
Drive other apps, not just the page
—
system.tree · system.tap · agent.run
Share it with strangers safely
Store review
Sandboxed UGC domain, separate Lua state

Features

Every layer, scriptable.

From the pixels on the toolbar down to the C++ services behind chrome:// pages.

Lua 5.4 in the browser process

Scripts load from files/lua/ at startup. Local scripts get the full standard library — io, os, debug, require. Your device, your rules.

lemurx.tabs · net · http · fs · db · timer

Whole DevTools Protocol

Every CDP domain against every tab, iframe, worker and service worker — plus a browser-level target. v8.eval, dom.query, ax.tree, network emulation, geolocation, UA overrides.

lemurx.cdp · v8 · dom · ax · emulation

Skins & UI surgery

Persistent themes, a declarative widget tree mounted on nine slots in the real shell, and a scalpel for the native View hierarchy: style, replace, insert, detach, move, on.

lemurx.theme · ui.render · ui.style

luakit, on a phone

The complete C-level Lua API of luakit re-implemented on Chromium: widget{} trees mapped to Android views, webview bound to a tab, luakit.register_scheme, sqlite3, regex, soup, stylesheet, timer, download, ipc_channel. An rc.lua written for luakit runs here.

widget · webview · luakit.register_scheme

Network rules

Block, redirect, add or strip headers, rewrite response bodies with string replacements. Pattern-matched, per resource type, applied in the browser process before anything renders.

lemurx.net.addRule

Lua in the renderer

One lua_State per renderer process with page, dom_document and dom_element on real V8 handles, a synchronous send-request hook on every subresource, and luakit.register_function to expose Lua to page JavaScript.

page · dom_document · send-request

An automation base for AI agents

Observe → act, in three layers and one coordinate system: the page (screenshot, set-of-marks, CDP), the browser shell (ui.dump, ui.find) and other apps through an accessibility service the user turns on once. Deciding is your model's job; agent.run is the loop.

lemurx.agent · lemurx.system

Two trust domains

Local scripts are yours and run unrestricted. Shared scripts (UGC) run in their own lua_State with safe libraries only — no privileged API, no shared globals, no confused-deputy path back into yours.

files/lua/ vs files/lua/ugc/

Discoverable from the REPL

lemurx.help() prints the whole catalog, lemurx.help("tabs") one module, and lemurx.catalog is the same list as a table. lemurx.ui.dump() shows the native view tree, lemurx.cdp.targets() every DevTools target. You never have to read our source.

lemurx.help · catalog · ui.dump

Show me the code

Real scripts. Real browser.

Each of these is a complete file. Save it to files/lua/, restart Lemur, done.

files/lua/10_clean.lua
-- Block trackers at the network layer, strip leftovers in every frame.
lemurx.net.addRule({
  match  = "*://*.doubleclick.net/*",
  action = "block",
})

lemurx.tabs.on("document", function(ev)
  lemurx.tabs.inject(ev.id, [[
    document.querySelectorAll('.ad, [id^="ad-"], [class*="sponsored"]')
            .forEach(function (e) { e.remove(); });
  ]], { world = "isolated", frames = "all" })
end)

Architecture

Thin sugar. Thick access.

One Lua thread, one JSON protocol in each direction, and every Chromium layer on the other side of it.

Your scripts
files/lua/*.lualocal · privileged · full stdlib
files/lua/ugc/*.luashared · sandboxed · own lua_State
▼
lemurx.* API
init.luasugar: proxies, DSLs, async/await, help()
C bindingslua_CFunction · privilege checks · callback registry
▼
Hosts
Java hostUI · skins · widgets · menu · intents · accessibility service
C++ nativeprefs · permissions · cookies · history · net rules · custom schemes · renderer Lua
DevToolsDevToolsAgentHost per tab / frame / worker / browser
▼
Chromium 154 stable · Android
Browser processthe Lua runtime lives here, on a single sequenced thread

Single-threaded Lua

All scripts run on one sequenced thread. UI work is posted to the UI thread and awaited. Java callbacks that need a return value are refused instantly when Lua is busy — no UI↔Lua deadlock, ever.

Stock when idle

Every hook added to Chromium — URL-loader and navigation throttles, certificate override, custom schemes, back press, app menu, renderer Lua — is gated on state that only a script can create. With no script running each hook is an early return and the browser behaves like the official build it was compiled from.

The user always wins

The three-dot menu always ends with a plain Android switch for the Lua runtime that no Lua API can reach or hide. If the process dies twice within 20 s of starting scripts, the runtime disables itself and the browser comes up stock — a script can never lock you out of the browser you need to fix it.

Scripts

Share scripts.
Sandboxed by design.

Anything in files/lua/ugc/ is a shared script: it gets the browser-facing API — tabs, network rules, HTTP, UI widgets, storage — and nothing that could read your cookies, history, or reach the DevTools Protocol. Each one runs in its own Lua state, so it can't touch your globals or ride your privileged callbacks.

  • Text-only load, no bytecode, no dofile
  • No lemurx.cookie · history · cdp · prefs · system · luakit natives
  • fs jailed to lua/ugc, http.fetch capped at 2 MB / 20 s
  • lemurx.ugc.scan(src) lints for forbidden calls before you publish
  • Local scripts can expose() a curated function for UGC to import()
lemurx.help("ui")
LemurX Lua 1.12.1  privileged=false
脚本:filesDir/lua/*.lua 本地特权;filesDir/lua/ugc/*.lua 可分享、无特权
调用:lemurx.help() 或 lemurx.help('tabs')

## 原生界面  (ui)
  show({id,type='button'|'text'|'edit', text, gravity, x, y, onClick})
  remove(id) clear()
  dump([{maxDepth,maxNodes,gone}])  -- 所有窗口,含工具抽屉 Dialog
  find({text,id,desc,class}) click(query) longClick(query)
  setText(query, text) getText(query) visible(query,false) enabled(query,false)
  dialog({title,message,ok,cancel,onOk,onCancel}) alert() prompt()
  shell()  -- 底栏/地址栏/搜索框已知 id + 是否还在
  children(query)  replace(query, tree)  insert(query, tree[, {position='after'|'before'|'into'}])
  detach(query) restore([query]) move(query, {parent,index,before,after})
  on(query, 'click'|'longclick'|'touch'|'focus'|'text', fn[, {consume,move,max}])  off(key|'*')

Extensions

Your extensions already work.

Lemur runs the same extension engine as desktop Chromium. Install straight from the Chrome Web Store or Edge Add-ons, drop in your userscripts, and keep the setup you've spent years tuning — on a phone.

uBlock Origin
Dark Reader
Bitwarden
Tampermonkey
AdGuard
Grammarly
1Password
Notion Web Clipper
LastPass

Extensions get their own toolbar slot, popups render as bottom sheets, and Lua can talk to them — lemurx.ui.render("toolbar.end", …) sits right next to their icons.

Avatar try-on and marketplace trading on a phone

Roblox power users

The metaverse,
with the pro tools on.

A huge share of Lemur's community lives on Roblox — and they refuse to trade without their extensions. RoPro, BTRoblox and Roblox+ run on Lemur exactly as they do on desktop: try outfits on your avatar before you buy, watch limited-item prices, get trade notifications, and flip items from the phone in your pocket.

RoProTrade values, outfit try-on, server filters
BTRobloxBetter catalog, item history, profile tools
Roblox+Trade & friend notifications, quick actions
  • Desktop-mode Roblox pages that stay in desktop mode — per-site, remembered
  • Extension popups as bottom sheets, thumb-reachable
  • Write your own price alerts in ten lines of Lua with lemurx.timer + lemurx.http

Freedom

The most customizable
mobile browser on Earth.

Every other mobile browser gives you a theme picker. Lemur gives you the toolbar, the tab strip, the gestures, the network stack and the rendering pipeline — and a scripting language to rewire them. If you can describe it, you can ship it to yourself tonight.

SkinsPersistent themes, per-site overrides, your own widget tree in the shell
ExtensionsChrome, Edge, userscripts — thousands of them, unmodified
LuaFull browser-process access, Lua in every renderer, luakit widgets on real Android views
BehaviourBack-gesture, omnibox, downloads, UA, headers: all interceptable
Three phones running Lemur with completely different custom skins

Engine

Rides the newest Chromium.

Customization is worthless on a stale engine. Lemur rebases onto each new Chromium stable so the security patches, V8 speedups and web-platform features land in your hands when they land in Chrome's.

Stable

Upstream site isolation, sandboxing and the same-day security fixes Chromium ships. Lemur's additions live beside Chromium's code, not on top of a fork that drifts.

Fast

Current V8, Skia and the latest Android graphics path. Lua runs on its own thread and never touches the render pipeline unless you tell it to.

Private

No account required, no tracking baked in. Block at the network layer, strip headers, kill third-party cookies — and audit every rule from Lua, because the rules are yours.

Bookmarks, extensions and Lua scripts syncing between phone, tablet and laptop

Sync

Bookmarks. Extensions. Scripts.
Everywhere you are.

Sign in once and your Lemur follows you. New phone? Restore the toolbar you built, the extensions you trust and the Lua scripts you wrote — in the order you installed them, with their settings.

  • Bookmarks & reading list — the usual, plus folder order and favicons
  • Extensions — IDs, enabled state, per-extension options where the extension allows it
  • Lua scripts — files/lua/ as a versioned bundle; roll back any script to any previous version
  • Sync is opt-in per category; scripts flagged -- @nosync stay on the device

Lineage

Picking up
Kiwi's baton.

Kiwi Browser proved that a phone browser could run real extensions — then, in January 2025, its founder archived the project after nearly seven years of solo maintenance. The idea was too good to let die. Lemur carries it forward as a commercial, closed-source browser that opens as much as it possibly can through Lua: extension-first, scriptable to the native layers, built so that what you need actually comes true.

"I just wanted extensions on mobile for myself." — Arnaud Granal, on why Kiwi existed
  • Kiwi users: your extensions install the same way, your bookmarks import in one tap
  • Closed source, open to you: every layer we can expose through Lua, we do — and we keep pushing that line
  • More open, more free, more extensible: the three words we measure every release against

If you're a hacker, Lemur was built for you.

Relay baton passed from the Kiwi Browser icon to the Lemur icon
A creator community hub sharing extensions, userscripts and Lua scripts

Community

Build it. Share it.
Watch it spread.

Lemur's UGC community is one place for every kind of add-on: browser extensions, userscripts, and Lua scripts that reach all the way down into the native layers. Publish with one tap, fork anyone's work, remix it, and ship it back. The freedom to create is what turned a browser into a movement.

ExtensionsCRX packages, curated collections, one-tap install
UserscriptsGreasemonkey-style scripts with site targeting
Lua scriptsSkins, HUDs, network rules, deep native tweaks
  • Every shared Lua script runs sandboxed in its own state — creators get freedom, users keep safety
  • Versioned publishing, forks and changelogs; roll back any install to any version
  • Ratings, comments and collections surface the best ideas; lemurx.ugc.scan() lints before you publish
  • Local scripts can expose() curated APIs for community scripts to build on

Ecosystem

UGC powered by Paip.AI.
One shared ecosystem.

Paip.AI is the interest-based social app the founding team built between 2024 and 2026 — real people, real posts, and smart matching that finds friends on your wavelength. Lemur's UGC community runs on Paip.AI's technology and shares one ecosystem with it: one identity, one creator profile, one feed where a Lua script, a skin or an extension collection travels as naturally as a post.

  • Publish a script in Lemur and it lands on your Paip.AI profile — followers, likes and comments carry over
  • Interest matching recommends scripts and skins from creators on your wavelength, not just the most downloaded
  • One account for both: sign in to Lemur with Paip.AI and your UGC library follows you
Paip.AI
Paip.AIFind your vibe
× LemurX
Paip.AI home feed

Our mission

Six years. Five million geeks.
One browser that answers to you.

Lemur was born in 2020 with a stubborn idea: the person holding the phone should have the final say over the software on it. Six years later, five million power users across the world make Lemur their first choice — not because it's the prettiest browser, but because it's the only one that does exactly what they tell it to.

2020first release
6years shipping
5,000,000geeks who chose Lemur
#1pick of power users worldwide
  1. 2020Lemur ships: a Chromium for Android that runs Chrome extensions, when almost nothing else on mobile did.
  2. 2021–2023Desktop mode, per-site skins, ad and tracker blocking at the network layer. The Roblox community arrives and never leaves.
  3. 2024On 6 March, Kevinlinpr steps down as CEO and the founding team leaves to build Paip.AI, an interest-based social app.
  4. 2025Kiwi Browser is archived. Lemur commits to keeping mobile extensions alive and open.
  5. 2026On 6 September, Kevinlinpr buys back 100% of the company and retakes the helm — and makes the boldest call in Lemur's history: a Lua runtime inside the browser process, with every native layer open to it. The next-generation Lemur launches at the end of 2026.

The founders are back.

On 6 March 2024, Kevinlinpr stepped down as CEO and the founding team left the company to build Paip.AI, an interest-based social app. On 6 September 2026, Kevinlinpr bought back 100% of the company and returned to take charge of Lemur's future. The brief is simple: open every layer, ship on the latest Chromium, and never make a decision the user can't override. The freedom we promised six years ago is about to get a lot bigger.

  • KKevinlinprChief Executive Officer
  • SShirleyChief Design Officer
  • DDeaconChief Architect
  • AAllenTomChief Technology Officer

Next-generation Lemur — arriving end of 2026

Get Lemur.

Next-generation Lemur arrives end of 2026. The current Lemur Browser is on Google Play today.

Android 8.0 or newer · arm64 · latest Chromium stable · Lua 5.4.7 · Chrome & Edge extensions · userscripts

Then drop a .lua file into the app's files/lua/ directory, restart, and watch lemurx.help() print the whole API in logcat.