Skip to content

Project Structure

aaalllexxx edited this page Jun 29, 2026 · 1 revision

Project Structure

A typical ENPAF project looks like this:

myapp/
├── enpaf.json          # project configuration (see enpaf.json Configuration)
├── main.py             # Python entry point — creates EnpafApp, defines handlers
├── icon.png            # app icon (referenced by enpaf.json "icon")
├── app/                # the web frontend (served as-is)
│   ├── index.html      # main page
│   ├── css/
│   │   └── style.css
│   ├── js/
│   │   └── app.js
│   ├── pages/          # additional HTML pages
│   │   └── about.html
│   └── img/            # static images
├── data/               # local runtime data (SQLite DB in dev) — gitignore this
└── dist/               # build output (.apk) — gitignore this

What each piece does

main.py

The Python entry point. It creates an EnpafApp, registers routes, bridge handlers, and event listeners, and calls app.run(). On a phone, app.run() detects Android and starts the WebView runtime; on desktop it starts the dev server. See Python API.

from enpaf import EnpafApp
app = EnpafApp(__name__)
# ... routes / handlers / events ...
if __name__ == "__main__":
    app.run()

app/

Your UI — plain HTML/CSS/JS. There is no bundler and no build step; files are served directly. In dev they're served by Flask; on-device the same files are packaged into assets/www/ and loaded by the WebView via file:///android_asset/www.

  • app/index.html is the entry page (required).
  • The ENPAF JS bridge (enpaf.js) is injected into the <head> automatically.
  • Reference assets with relative paths (css/style.css, js/app.js) so they resolve both in dev and on-device.

enpaf.json

All project metadata: app name, Android package, version, permissions, hardware features, deep links, Python pip requirements, SDK levels, theme, and signing config. Full field reference: enpaf.json Configuration.

data/

Writable runtime data. In dev, the SQLite database lives here (data/enpaf_data.db). On-device, the DB is redirected to the app's private files directory via the ENPAF_DATA_DIR environment variable (the source tree is read-only inside the APK). Add data/ to .gitignore.

dist/

Where paf build copies the finished APK (<name>-<version>.apk). Add dist/ to .gitignore; publish APKs via Releases instead.

Where the build actually happens

paf build generates a full Gradle/Chaquopy Android project in a build directory and runs Gradle there. By default that's .enpaf_build/ inside the project, but if the project is under OneDrive it's relocated to %LOCALAPPDATA%\enpaf\builds\<name>-<hash> (overridable with ENPAF_BUILD_DIR). The generated project and Gradle caches are disposable — only dist/ matters.

Recommended .gitignore

__pycache__/
*.py[cod]
*.egg-info/

# Build / distribution
build/
dist/
*.whl
*.tar.gz

# ENPAF build output
.enpaf_build/

# Runtime data
data/
*.db
*.db-shm
*.db-wal

# Secrets
.pypirc

The framework repository layout

If you're working on ENPAF itself (not just an app), the package is organized as:

enpaf/
├── __init__.py            # exports EnpafApp, __version__
├── core/                  # app, bridge, events, router, storage, api, server
├── android/               # capability modules + Android runtime
├── builder/               # APKBuilder + ProjectGenerator (Gradle/Chaquopy)
├── cli/                   # the `paf` command (create/run/serve/build/doctor)
└── template/              # the `paf create` scaffold
enpaf_bridge/              # enpaf.js (the JS SDK) + socket.io client
tests/                     # pytest suite
.github/workflows/         # CI + release automation

See Architecture for how these fit together.

Clone this wiki locally