Preswald: Shipping Python Data Apps as Single-File HTML via WASM
Preswald is a WASM packager for Python-based interactive data apps: bundle full complex data workflows, particularly visualizations, into single files, runnable completely in-browser, using Pyodide, DuckDB, Pandas, and Plotly, Matplotlib, etc. Build dashboards, reports, and notebooks that run offline, load fast, and share like a document.
At a glance
- What is it?
- Preswald packages Python data apps built on Pyodide, DuckDB, and Plotly into static HTML files that run entirely in the browser. This review examines its mechanism, configuration, limitations, and who should adopt it.
- Who is it for?
- Preswald is for analysts and engineers who need to hand a data dashboard or report to someone who cannot or should not install Python, and who value offline, local execution and single-file distribution. It is not for teams building multi-user, server-backed applications with complex authentication or large, frequently updated datasets, because the entire data payload ships to the browser.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 96 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 September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem: Data Apps That Refuse to Be Documents
Most Python data apps fall into two camps. One is the notebook, which needs a Python kernel and a server to run. The other is the dashboard framework, which typically requires a backend process, a database connection, and a deployment pipeline. Both fail when the recipient is a stakeholder who should not install anything, or when the environment is air-gapped and cannot reach a package index. Preswald targets that gap. It turns a Python data app into a static HTML file that runs compute, data access, and UI in the browser via WebAssembly. The README calls it a static-site generator for interactive data apps. The intended user is someone who wants to bundle logic, UI, and data into a shareable artifact, not someone who wants to maintain a live service.
How Preswald Works: Pyodide, DuckDB, and a Reactive DAG
Preswald's runtime is built on Pyodide, which compiles Python to WebAssembly so it executes in the browser without a server. DuckDB runs alongside it, giving in-browser analytical queries over the bundled data. The UI components, such as tables and charts, are prebuilt and composed in Python. The reactive engine tracks dependencies between state and UI elements, and according to the README, it only re-runs what is needed, powered by a DAG of dependencies. When you run preswald export, the tool packages your Python code, the data files, and the DuckDB queries into a static site inside dist/. The resulting folder contains everything needed to run the app locally or share it. The key architectural consequence is that the browser does the computation. There is no server-side Python process after export, which is what enables offline use and single-file distribution.
Getting Started: Commands and Project Layout
Installation is straightforward with pip or uv: pip install preswald or uv pip install preswald. The quick start sequence is preswald init my_app, then cd my_app, then preswald run. That creates a folder with a specific structure: hello.py for app logic, preswald.toml for metadata and config, secrets.toml for API keys, data/sample.csv for input files, and images/logo.png for branding. In hello.py you import from preswald, such as text and table, and use get_df to load a CSV. A minimal app is text("# Hello Preswald"), df = get_df("sample.csv"), table(df). Running preswald run launches a development server, typically at http://localhost:8501. The export command, preswald export, builds the static site into dist/. This is a real workflow, not a hypothetical one, and the commands are concrete enough to follow without deeper documentation.
Configuration: preswald.toml Controls Metadata, Branding, and Logging
Configuration lives in preswald.toml, an INI-style file with sections for project, branding, and logging. The project section sets title, version, port, slug, and entrypoint. The entrypoint points to your main Python file, hello.py in the default layout. Branding controls the app's name, logo, favicon, and primary color, which matters because the exported HTML is a self-contained document and you likely want it to look like your product. Logging configuration is also present, with level and format keys, mirroring standard Python logging. This is a thin but practical config surface. Notably, there is no section for runtime dependencies or data source definitions beyond what get_df infers from the data directory. The README does not show how to add custom Python packages beyond Pyodide's built-in set, which is a constraint worth noting.
The Export Pipeline: What You Actually Ship
The export command is the heart of Preswald. It produces a static site in dist/ that contains all files needed to run the app locally or share it. The README lists what is preserved: app UI, logic, and reactive state. It works offline in any modern browser, and it bundles Python code via Pyodide, data, and DuckDB queries. The output is a file folder, not necessarily a single .html file despite the marketing language. The README says 'one command creates a fully-packaged .html app' but also says the folder can be shared or embedded. For a true single-file deliverable, you may need to zip the folder or host it. This is a minor discrepancy, but it matters for stakeholders who expect a single attachment. The practical benefit is that the recipient opens the file and the app runs, no installation, no network access required after the initial load.
Limitations and Failure Modes
Preswald is not the right tool for every data app. Because the browser executes Pyodide and DuckDB, the entire dataset must be loaded into the browser's memory. Large data files will bloat the HTML or folder size and may exhaust browser memory. The README claims it runs offline 'even with large data', but 'large' is relative to client hardware, and there is no server-side aggregation to slim data before it ships. Another limitation is dependency availability. Pyodide has a curated set of packages; not every PyPI package is available in WASM. The README lists Pandas, Plotly, and Matplotlib as supported, but if your workflow relies on a less common native library, it will not work. Also, the reactive DAG is a custom engine, and debugging state updates in a browser environment is harder than in a normal Python process. Finally, secrets.toml is mentioned, but shipping secrets in a client-side app is a security risk. The README says apps are 'secure by default' because they run locally, but any secret embedded in the bundle is visible to the user. That is a failure mode to plan around.
Alternatives: Streamlit and Voila Take a Different Path
The most direct alternative is Streamlit, which also lets you build Python data apps with minimal code. But Streamlit runs as a server-side application: the Python process executes on a host, and the browser only renders the UI. That means the user needs network access to the server, and the app is not a static file. Preswald's WASM approach moves the Python runtime into the browser, which enables offline use and file sharing. Voila is another alternative; it converts Jupyter notebooks into interactive dashboards, but it also requires a running kernel. The difference is fundamental: Preswald trades server-side flexibility for client-side portability. If you need server-side computation, large data, or multi-user state, Streamlit or Voila are more appropriate. If you need a document that runs anywhere, Preswald's approach is unique in this comparison.
Maintenance, Licensing, and Upgrade Considerations
Preswald is under active development, with recent releases v0.1.59, v0.1.58, and v0.1.57 in May and June 2025. The project is not archived, and the last push was June 2026, indicating ongoing maintenance. The license is Apache-2.0, which is permissive for commercial use, but you should read the license text for specifics. The README does not discuss upgrade paths or breaking changes. As a version 0.x project, you should expect API changes between releases. The reactive engine and export pipeline are custom, so upgrading Preswald may require re-testing your apps. There is no mention of a migration tool or changelog in the provided material. The documentation site (docs.preswald.com) likely holds more, but it is not in this repository description. For a tool that packages apps into a distributable format, version pinning is advisable, because the output format may change between releases.
Editorial conclusion
Preswald is for analysts and engineers who need to hand a data dashboard or report to someone who cannot or should not install Python, and who value offline, local execution and single-file distribution. It is not for teams building multi-user, server-backed applications with complex authentication or large, frequently updated datasets, because the entire data payload ships to the browser. Before adopting, verify that your target browser supports the required WASM features, that your data size stays within practical memory limits, and that your Python dependencies are available in the Pyodide distribution. If you need server-side processing or real-time collaboration, consider a traditional web framework instead. Preswald's approach is genuinely file-first, and that is its strongest boundary.
Community notes