Self-hosted service
Kitware/trame avatar
Kitware/trame

Trame: building desktop-like web apps in plain Python

Trame lets you weave various components and technologies into a Web Application solely written in Python.

705 stars88 forksPythonNOASSERTION

At a glance

What is it?
Trame is a Kitware framework that turns a Python script into an application with a browser front end, wiring VTK and ParaView for 3D and other libraries for the rest. It installs from pip, runs locally, remotely, in the cloud, in Jupyter or on HPC, and its 4.0 release moved the server and client packages to a new major version.
Who is it for?
Adopt Trame when your team writes analysis in Python and needs to put a UI around it without learning a JavaScript framework, especially if the content is 3D and you already have VTK or ParaView in the pipeline. Do not adopt it if you need a front end that a JavaScript team can own, or if the deployment environment forbids the browser as the client, since the whole model assumes a browser talking to a Python server.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 26 days ago.
What is it written in?
Mainly Python, 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

A Python script that presents itself as an application

Trame is described as an easy-to-use, Python-based framework that lets you create a desktop like application which shows up in your web browser. The name is the point, as the README explains: trame is French for the core that ties things together, and for a guide providing the essence of a task.

The concrete scope is broad but specific. You can create buttons, dialogs, 3D scenes with VTK and ParaView, charts and maps, and the framework is pitched at micro apps, dashboards, and at replacing a PyQt app with a web one. The README also suggests using it in development, for example when tweaking or configuring 3D rendering and machine learning work.

What makes it different from a plotting library is that the deliverable is an application rather than a figure. The same application can act as a local desktop app or as a remote cloud app, both accessed through a browser, and the README states that at the end your app can be used locally, remotely, in the cloud, in Jupyter or on HPC. That list is the design goal in one sentence: write the analysis once in Python, and choose the deployment context later.

The project comes from Kitware, the company behind VTK and ParaView, which explains both the 3D emphasis and the fact that the whole thing is Python only.

Local and remote rendering through one method

The 3D section makes the core architectural claim: with VTK and ParaView at its core, Trame provides complete control of 3D visualizations and data movements, and developers benefit from a write-once environment while Trame exposes both local and remote rendering through a single method.

That single method is the whole design idea. The same code path renders on the machine running the server, in the browser next to the Python process, or on a rendering node somewhere else, because the communication is a defined protocol rather than an in-process call. The Trame Tutorial and the API Reference are linked from the README as the places to learn the library, and the API reference lives on readthedocs.

The rest of the stack is assembled rather than written. Trame builds on existing libraries and tools, and the README names Vuetify, Altair, Vega, deck.gl, VTK and ParaView among them, so charts and mapping components come from established projects rather than from a bespoke widget set.

The framing in the README is that by relying simply on Python, Trame focuses on the data and its analysis and visualisations while hiding the complications of web app development. The honest reading is that you accept a specific way of doing web development, with a server in Python and a client in the browser, in exchange for not writing that layer yourself.

pip install trame, and the optional extras that decide your deployment

Installation is a single command:

bash
pip install --upgrade trame

That gets you the core infrastructure, and the README is explicit that more advanced usage may require additional dependencies. The list is the deployment decision in disguise:

* `pywebview` : Needed for desktop usage (--app) * `jupyterlab` : Needed to run inside jupyter-lab * `notebook` : Needed to run inside jupyter-notebook * `requests` : Needed when using remote assets such as GDrive files

So if you want the desktop mode, you install pywebview, and if you want the app to run inside a notebook environment, you install jupyterlab or notebook. The last entry is easy to overlook: remote assets such as files hosted on Google Drive need requests, which is a hint that a Trame app can pull in data from elsewhere rather than only working on local files.

The package metadata confirms the shape of the project. The project name is trame, the version is 4.0.0, the description is a framework to build applications in plain Python, and it requires Python 3.10 or later. The runtime dependencies are trame-server 4 to 5, trame-client 4 to 5, trame-common 1.2.7 to 2 and wslink 2.5.7, plus pyyaml for trame.tools.widgets. The optional dependency groups are named app, jupyter and dev, and the build backend is hatchling.

Trame is also available on conda-forge, and the README mentions docker images for cloud deployment, so the same code has three distribution channels depending on how much control you want over the environment.

Environment variables that control the websocket link

Three environment variables are documented, and they are all about the connection between the Python server and the browser client rather than about your application logic.

* `TRAME_LOG_NETWORK` : Path to log file for capturing network exchange. (default: None) * `TRAME_WS_MAX_MSG_SIZE` : Maximum size in bytes of any ws message. (default: 10MB) * `TRAME_WS_HEART_BEAT` : Time in second before assuming the server is non-responsive. (default: 30s)

The message size limit is the one that bites. Ten megabytes is the ceiling for a single websocket message, and a Trame application that ships volumetric data or large arrays to the client will hit that wall, at which point the limit becomes a tuning decision rather than a default. The heart beat setting decides how long the server waits before it assumes the client has gone away, which matters on flaky networks and on HPC nodes where the browser is somewhere else entirely.

The network log path is the debugging tool. When a Trame application misbehaves, being able to capture the actual exchange between client and server is often faster than reading application logs, and it is a one environment variable away.

None of the three are exposed through the Python API, which is consistent with the rest of the configuration story: operational knobs live in the environment, application state lives in Trame.

Life cycle callbacks and the shared state with reserved entries

Two extension points are documented in detail. The first is the life cycle, managed on the application controller and prefixed with on_.

* `on_server_start` : Executed at server.start() call while passing the server as argument. * `on_server_bind` : WSLinkServer is getting bound to trame so you can attach your own routes. Its instance will be passed as argument to callback. * `on_server_ready` : All protocols initialized and available for client to connect * `on_client_connected` : Connection established to server * `on_client_exited` : Linked to browser "beforeunload" event * `on_server_exited` : Trame is exiting its event loop * `on_error` : JS error forwarded (msg:str) on the python * `on_exception` : Server exception occurred when interacting with the UI. The exception instance is provided as arg. * `on_server_reload` : If callback registered it is used for reloading server side modules

That list tells you a lot about the runtime. on_client_exited is tied to the browser's beforeunload event, so a closed tab is a known event rather than a dropped connection. on_error forwards a JavaScript error to Python as a string, which means a client side exception can be logged or handled server side. on_server_reload exists for reloading server side modules, and on_server_bind is your hook for adding your own routes to the WSLinkServer.

The second mechanism is the shared state, which the README describes as allowing the server to synchronised with the client. Because Trame reuses that state internally rather than inventing a parallel mechanism, internal variables are prefixed with trame__* to avoid conflicts with user state. Two entries are writable: trame__favicon, to replace the displayed favicon with an image encoded url, and trame__title, to replace the page title. Two are read-only: trame__busy, which reports whether requests are pending a server response, and tts, which the excerpt does not describe.

Version 4 moved the server and client packages

The release history shows a major version landing recently. The tags are v4.0.0 on 2026-09-09, v3.13.2 on 2026-05-15 and v3.13.1 on 2026-05-11, and the last push to the repository was on 2026-09-28. So the 4.0 line is roughly a month old at the time of writing, and the 3.13 patch line before it.

The version bump is not cosmetic, because the dependency ranges in the project metadata are trame-server>=4,<5 and trame-client>=4,<5. A Trame 4.0.0 installation therefore requires the 4.x server and client packages, and a project that pinned trame-server 3.x will not resolve against it. For an application, that means the upgrade is a coordinated move across the client and server packages rather than a version bump in one place, and the major version boundary is where to expect API work.

The release process is automated. The project uses semantic-release, with the version written to pyproject.toml and to src/trame/__init__.py, a build command that creates a virtual environment and runs python -m build, and a publish step that uploads the built distribution to the version control release. The project classifies itself as Development Status :: 5 - Production/Stable, requires Python 3 or later only, and is operating system independent.

The repository itself carries the usual Kitware project furniture: a CHANGELOG.md, a CONTRIBUTING.rst, a pre-commit configuration, ruff settings with a line length of 88 and a py310 target, flake8 and codespell configuration, codecov and coveragerc files, a readthedocs configuration and a docker directory. The examples directory is organised by topic, from 00_howdoi and 01_Tutorial through vuetify, markdown, trame-components, charts, vtk, paraview, pydeck and advanced, plus blogs, core_features, data, deploy, jupyter and validation directories.

Editorial conclusion

Adopt Trame when your team writes analysis in Python and needs to put a UI around it without learning a JavaScript framework, especially if the content is 3D and you already have VTK or ParaView in the pipeline. Do not adopt it if you need a front end that a JavaScript team can own, or if the deployment environment forbids the browser as the client, since the whole model assumes a browser talking to a Python server. Verify first that the optional dependencies match your use, pywebview for the desktop mode, jupyterlab for Jupyter, and that you have read the environment variables, TRAME_WS_MAX_MSG_SIZE and TRAME_WS_HEART_BEAT, before you push large payloads over the websocket, and check that the trame-server 4.x and trame-client 4.x packages you pin are the ones your code expects, since version 4.0.0 changed the major version of both.

Frequently asked questions

What is Trame?

Trame is a Kitware framework for building interactive web applications in plain Python, with desktop like behaviour in the browser. It exposes both local and remote rendering through a single method and can produce buttons, dialogs, 3D scenes with VTK and ParaView, charts and maps.

How do I install Trame and run it in Jupyter?

Install the core with pip install --upgrade trame, then add the optional dependency you need: jupyterlab to run inside jupyter-lab, notebook to run inside jupyter-notebook, and pywebview for the desktop mode with --app. The project also ships on conda-forge and as docker images for cloud deployment.

What are the Trame environment variables?

TRAME_LOG_NETWORK is a path to a log file capturing the network exchange, TRAME_WS_MAX_MSG_SIZE caps the size in bytes of any websocket message with a default of 10MB, and TRAME_WS_HEART_BEAT is the time in seconds before the server assumes the client is unresponsive, defaulting to 30s.

What changed in Trame 4.0.0?

Version 4.0.0 was released on 2026-09-09 and the package metadata requires trame-server 4 to 5 and trame-client 4 to 5, so the major bump applies to the server and client packages as well. The project requires Python 3.10 or later and builds with hatchling.

Official sources

  1. Issues
  2. Kitware/trame on GitHub
  3. Project website
  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/kitware-trame.svg)](https://hysenlabs.com/projects/kitware-trame)

Was this useful?