Library / SDK
obsproject/obs-browser avatar
obsproject/obs-browser

obs-browser: the browser engine inside OBS Studio and its JavaScript bindings

CEF-based OBS Studio browser plugin

911 stars271 forksC++GPL-2.0

At a glance

What is it?
obs-browser is the CEF based plugin that gives OBS Studio a Browser Source, browser docks and service integration, plus a window.obsstudio object that lets a web overlay read and drive the application. It ships inside official OBS packages, and it is the piece you have to learn before you can build a dynamic overlay.
Who is it for?
obs-browser is the right foundation for anyone building a live overlay that has to react to OBS state, and the permission levels give you a way to keep a read-only widget read-only. It is the wrong tool for a Linux streamer on Wayland, where service integration and browser docks are unavailable, and for anyone who needs a desktop capture of an application that the CEF sandbox will not render.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why a browser lives inside a streaming application

OBS Studio composites scenes from sources, and until a browser engine was embedded in the program, every dynamic graphic in a scene had to be a static image or a separate window captured by a display source. obs-browser changes that by embedding the Chromium Embedded Framework, so a scene can hold a source that renders a real web page with the full set of modern browser APIs. The practical effect is that a lower third can be a Vue, React or plain HTML application that reacts to what the streamer is doing, instead of a PNG that a compositor re-renders by hand. The plugin also covers two adjacent features that follow from having a browser in the box. Service integration lets the program link to third party services, and browser docks load webpages directly into the OBS interface itself, so a chat window or a control panel can sit beside the preview. The audience is therefore OBS users who build scenes, and developers who want to extend OBS without recompiling the whole application.

Linux on Wayland is the hole in the feature list

The platform story is not uniform, and the difference matters if you deploy to Linux. Service integration and browser docks are enabled on all supported platforms with one exception, Wayland on Linux. A Wayland session does not offer the same window embedding or inter process communication paths that the other platforms provide, so those two features are simply absent there rather than degraded. Browser Sources themselves are described as cross platform and are not called out as restricted, so the core value of the plugin, web content inside a scene, still works on Wayland. The practical consequence for a studio is that a workflow that depends on a dock for chat or for a remote control panel cannot be assumed portable across the Linux distributions your team uses. The official packages listed for the plugin cover Windows, macOS, the Ubuntu PPA and the official Flatpak, and the README notes that most Linux distributions are covered through those packages rather than through a separate download.

Included by default means you do not install it

This is the part that trips people up when they search for the plugin. The README states that the plugin is included by default in official packages on Windows, macOS, the Ubuntu PPA and the official Flatpak, and that this covers most Linux distributions. If you installed OBS Studio from an official source, the browser source is almost certainly already in the build, and there is no separate install step to find. The plugin appears in the interface as a source type you add to a scene, and the same page rendering machinery is what backs the docks. The corollary is that the plugin version you have is tied to the OBS build you have, and updating OBS is how you update the browser engine and the bindings together. It also means that a custom or third party OBS build may not carry the plugin at all, in which case the source type will simply be missing from the add source menu.

The window.obsstudio object and its event stream

A browser source is only interesting because it can talk back to the application hosting it. obs-browser exposes a global object, window.obsstudio, that gives a page access to some OBS specific functionality from JavaScript. The first thing to read is the plugin version, because the binding surface has changed across releases and an overlay written against an old build may call a function that no longer exists.

js
/**
 * @returns {string} OBS Browser plugin version
 */
window.obsstudio.pluginVersion
// => 2.17.0

Beyond version checks, the object pushes state changes to the page as DOM events on window. The documented list covers scene changes, transition changes, source visibility and activation, the streaming lifecycle, the recording lifecycle including pause and unpause, the replay buffer lifecycle, the virtual camera, and program exit. There is also a catch-all: any custom event emitted through obs-websocket vendor requests arrives the same way. That last entry is the extension point for teams who already run obs-websocket and want their own backend state to reach the overlay without inventing a new channel. The event list is long enough that reading the frontend API reference linked from the README is worthwhile before you design against it, since the descriptions live on the OBS documentation site rather than in this repository.

Permission levels decide which calls a page can make

Every function on window.obsstudio sits at a permission level, and the level is the whole security model of the binding. The scale runs from 0 for NONE through READ_OBS for OBS data, READ_USER for user data, BASIC, ADVANCED and 5 for ALL. Reading the current control level needs no permission at all, which makes it the right first call for a page that wants to know what it is allowed to do before it asks for anything. Reading output status needs READ_OBS, and reading scenes, transitions and the current scene needs READ_USER. Actions split along the same lines: saving the replay buffer needs BASIC, while starting it, stopping it, changing scene and changing transition need ADVANCED. Starting or stopping the stream, starting, stopping, pausing and unpausing the recording, and starting or stopping the virtual camera all need ALL. An overlay that only needs to know whether the stream is live therefore can run at a level far below the one that can stop the broadcast, and that separation is the reason to use these bindings instead of reaching for obs-websocket for everything.

Reading OBS state from a page

The call style is uniform: you pass a callback and the callback receives the data. Here is how a page checks what OBS is currently doing. The status object carries a boolean for recording, a separate one for recordingPaused, and booleans for streaming, replaybuffer and virtualcam. The recording flag is documented as not being affected by the pause state, which is a distinction that matters if your overlay shows a recording indicator.

js
/**
 * @param {ScenesCallback} cb - The callback that receives the scenes.
 */
window.obsstudio.getScenes(function (scenes) {
    console.log(scenes)
})

The scene listing is a plain array of names, and the current scene object adds the scene name with its width and height. Transitions follow the same pattern, with a list of transition names and a separate call for the one currently set. The control level call is the one to make first, and it looks like this.

js
/**
 * @param {LevelCallback} cb - The callback that receives the current control level.
 */
window.obsstudio.getControlLevel(function (level) {
    console.log(level)
})

A page that reads scenes but cannot change them is still useful, and the permission model is what allows that. Nothing in the interface requires the page to be trusted, only to be permitted at the right level.

Changing scenes and driving the output

The write side is thin, and that is deliberate. Changing the current scene takes a scene name, changing the current transition takes a transition name, and both require ADVANCED. Everything that touches the actual broadcast needs ALL.

js
/**
 * @param {string} name - Name of the scene
 */
window.obsstudio.setCurrentScene(name)
js
/**
 * Does not accept any parameters and does not return anything
 */
window.obsstudio.startStreaming()

The replay buffer has a similar trio of calls, saveReplayBuffer at BASIC and startReplayBuffer and stopReplayBuffer at ADVANCED, and the recording calls startRecording, stopRecording, pauseRecording and unpauseRecording at ALL. The virtual camera is controlled with startVirtualcam and stopVirtualcam, also at ALL. If you are building a control surface for a second operator, these are the calls you will want, and the calls you cannot have without the highest level are the ones that could interrupt a live broadcast. The functions that take no parameters and return nothing are the awkward ones to design around, because a page has no return value to react to and no completion callback to chain on. You would pair them with the event stream instead, waiting for obsStreamingStarted or obsRecordingStopped rather than assuming the call did what it said.

Building an overlay: the practical steps

There is no separate command to run because the plugin ships with OBS. The work happens in your overlay project. If your overlay is written in TypeScript, the bindings have type definitions published to npm and yarn, and installing them as a dev dependency is the whole setup step.

sh
# npm
npm install --save-dev @types/obs-studio

The yarn equivalent is the same package under the dev flag, and the type definitions describe the window.obsstudio object, the event names and the callback signatures. After that you point a Browser Source at your local page while you develop, and at a hosted URL when the scene goes out. Two things to keep in mind as you write the page. First, the browser engine is CEF, so anything you rely on has to work in that engine rather than only in your own desktop browser, and a page loaded from disk behaves differently from a page served over http. Second, write the page so that a missing permission produces a degraded view rather than an exception, because the same overlay code may run on a machine where the control level is lower than you expect. The repository itself does not document a build or install procedure for the plugin, since the README points readers to the packages that already contain it.

What the source tree shows about the CEF integration

The layout gives a clear picture of what this plugin is. The root holds browser-app.cpp and browser-app.hpp, which are the CEF application object, and browser-client.cpp with its header, which is the per browser client that ties a page to a source. browser-scheme.cpp implements a custom scheme so that local resources can be served to the embedded browser. There is a browser-dummy-client pair, which is the placeholder used when a page is loaded outside a real source context, and browser-config.h.in, a CMake template that bakes configuration into the build. DRM format handling sits in drm-format.cpp, the panel directory holds the dock and interface pieces, and obs-browser-page holds the bundled pages. The build is driven by CMakeLists.txt with a cmake directory, a deps directory for third party code, and cef-headers.hpp as the interface to the embedded framework. A clang-format configuration and a cmake-format configuration sit alongside them, so the project follows consistent formatting rules. The licence is GPL-2.0, and the COPYING file is at the root, which matters if you plan to redistribute a build that includes this code.

Maintenance signals: recent commits, older release tags

The repository is not archived, and the last push was on 2026-10-16, so the code is being changed. The release history visible in the repository looks different. The tagged releases named in the listing are Browser Source v1.31 from 2018-03-17, v1.30.1 from 2018-02-28 and v1.30 from 2017-07-18, which are the version numbers of the browser source rather than the version of the plugin as a whole. The plugin version reported at runtime, 2.17.0 in the example above, sits on a different numbering line from those tags, so do not read the age of the browser source tags as the age of the shipped plugin. The two facts together are what a maintainer can act on: work is landing on the branch, and the browser source component carries release tags that are old enough to make a version comparison with your own build misleading.

Editorial conclusion

obs-browser is the right foundation for anyone building a live overlay that has to react to OBS state, and the permission levels give you a way to keep a read-only widget read-only. It is the wrong tool for a Linux streamer on Wayland, where service integration and browser docks are unavailable, and for anyone who needs a desktop capture of an application that the CEF sandbox will not render. Before you commit, check the version reported by window.obsstudio.pluginVersion against the API you plan to call, because the binding surface has grown over several major versions, and confirm that the OBS build you ship to viewers carries the same plugin version.

Frequently asked questions

Do I need to install obs-browser separately for OBS Studio?

The README states that the plugin is included by default in official packages on Windows, macOS, the Ubuntu PPA and the official Flatpak, which covers most Linux distributions. If you installed OBS Studio from an official package, the browser source is already there.

Which obs-browser features are not available on Wayland?

Service integration and browser docks are the two features described as unavailable on Wayland on Linux. The cross platform Browser Source itself is not listed as restricted for that platform.

How do I check which obs-browser API version a page is running against?

Read window.obsstudio.pluginVersion from JavaScript in the page, which returns a version string such as 2.17.0. TypeScript users can install the @types/obs-studio package as a dev dependency to get definitions for the bindings.

What permission level does a browser source need to change the current scene?

setCurrentScene requires the ADVANCED level. Reading the current scene or the scene list needs READ_USER, and reading the current control level requires no permission at all.

Can an obs-browser overlay start or stop the stream?

Yes, startStreaming and stopStreaming exist on the window.obsstudio object, but both require the ALL permission level, the same level demanded by the recording and virtual camera calls.

Official sources

  1. Issues
  2. License: GPL-2.0
  3. obsproject/obs-browser on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/obsproject-obs-browser.svg)](https://hysenlabs.com/projects/obsproject-obs-browser)

Was this useful?