Skip to content

Project structure

File/directory Purpose
app.py Entry component and small-app logic
forge.json Entry, source root, title, packages and JS module configuration
styles.css Application stylesheet
public/ Explicit public assets and JS extensions
.forge-dev/ Generated development files; ignore in Git
dist/ Generated static application; normally ignore in source Git

For a larger app, split components into a Python package, for example frontend/pages.py and frontend/components.py, and set the entry to frontend.pages:App. Each part before the colon is a module path, and the part after it names the exported component.

Define the source boundary

{"entry":"app:App","source":"frontend","title":"My app"}

With this configuration, frontend/app.py becomes module app in the browser. Put only client-safe Python files in that folder. Source files are distributed to the browser and are inspectable, just like JavaScript.

The builder excludes hidden paths, common virtual-environment/build folders, node_modules, tests and bytecode. It rejects source/public symlinks. These filters are a convenience, not a reason to place secrets beside browser code.

public/ is relative to the project folder. public/logo.svg becomes /logo.svg in an origin-root deployment. Generated filenames such as index.html, boot.js and vendor/ are reserved.

Generated artifacts

python-app.zip contains framework and app Python code. react-runtime.js contains React and the bridge. The bootstrap loads Pyodide locally or from the pinned CDN URL. Build output also contains notices for bundled dependencies.

Read configuration and deployment before publishing an app.