Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ”¨ WebShell Forge

CI

Build native Android apps locally from plain HTML, CSS, and JavaScript.

You provide: an app name, a description, an icon, and your code. WebShell Forge stamps everything into a vendored copy of s17labs/webshell β€” a minimal Android WebView wrapper kit β€” and runs Gradle locally to produce an installable debug APK.

No cloud build services. No accounts. The generated apps are real Android apps with the INTERNET permission already declared, so they can make API calls and load remote content like any other app.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Dashboard (browser)  Β·  CLI wizard                 β”‚
β”‚    name Β· description Β· icon Β· HTML / CSS / JS      β”‚
β”‚    + live preview before you build                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  forge-core                                         β”‚
β”‚  1. copies the vendored webshell template           β”‚
β”‚  2. stamps applicationId / version into gradle      β”‚
β”‚  3. writes app_name (+ escaped strings.xml)         β”‚
β”‚  4. icon β†’ adaptive launcher icons (all densities)  β”‚
β”‚  5. writes assets/www/ and injects bridge.js        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  ./gradlew assembleDebug β†’ dist/*.apk               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Requirements (for building APKs)

Item Version
Node.js 20+
Java 17+ (AGP 8.7.3 requirement)
Android SDK platforms;android-35

Check your setup anytime:

npm run forge -- doctor   # or: forge doctor

Scaffolding works without Java/SDK β€” only the final Gradle build needs them.

Quick start

npm install

# Option A β€” web dashboard (form + live preview + streamed builds)
npm start                     # β†’ http://localhost:4321

# Option B β€” CLI wizard
npm run forge

Both frontends share the same core: they scaffold a project under projects/, stream the Gradle build log, and drop the finished APK into dist/ ready to adb install or sideload.

Using the CLI with existing files

forge create
# β†’ answers prompts for name/description/icon
# β†’ points it at ./index.html ./style.css ./app.js
# β†’ optionally builds immediately

What gets customized in the template

File Change
app/build.gradle.kts applicationId, versionCode, versionName
app/src/main/res/values/strings.xml app_name (quotes/apostrophes escaped safely)
res/mipmap-* replaced with adaptive icons generated from your image
app/src/main/assets/www/ your index.html, style.css, app.js + app.json metadata
(untouched) namespace = com.yourapp and all Kotlin sources β€” see note below

Why no source rewriting: webshell's docs explicitly allow namespace β‰  applicationId. The Kotlin package stays com.yourapp while each generated app gets its own unique applicationId, so side-by-side installs just work and we never touch fragile code.

The description is stored in assets/www/app.json (Android has no native "description" slot) and used for the APK filename.

Generated apps

  • Full-screen WebView loading assets/www/index.html
  • JS ↔ native bridge via bridge.js β€” auto-injected if missing (NativeBridge.toast(...), vibrate, etc.)
  • INTERNET + VIBRATE permissions pre-declared by the template
  • Debug-signed APK β†’ installs on any device (API 26+)

See the upstream docs for the full bridge API: bridge-api Β· gotchas-and-tips

Building on-device (experimental)

Forge itself is pure Node.js and runs fine on ARM64 phones (Termux / proot environments). Whether the Gradle build works there depends on your JVM:

java -version   # if this fails inside proot, try PROOT_NO_SECCOMP=1 java -version

If Java runs, npm run forge works end-to-end on-device β€” expect slow first builds (~5–15 min while Gradle + dependencies download; cached afterwards). If your container blocks JIT memory mapping, builds must run on a desktop until we ship a JVM-free pipeline.

Building with CI (no local Java needed)

The repo's own CI proves the full pipeline on every push: unit tests, then it scaffolds the sample app from the vendored template and runs ./gradlew assembleDebug on GitHub-hosted runners. The resulting APK is uploaded as the forge-sample-debug-apk artifact.

  • Download the latest sample APK: Actions β†’ CI β†’ latest run β†’ Artifacts
  • Rebuild on demand via the workflow's Run workflow button (workflow_dispatch)

You can also build your generated app in CI: scaffold locally (npm start or forge create), then use export and push:

forge export

Turns any scaffolded project into a ready-to-push repo with its own CI baked in:

forge create          # …answer prompts; say yes to "Export a CI-ready repo?"
# or later, for an existing scaffolded project:
forge export          # point it at ./projects/<id>

The exported folder contains the full Android project plus:

  • .github/workflows/build.yml β€” builds a debug APK on every push (and manual dispatch) and uploads it as an artifact
  • README.md β€” your name/description, build instructions, badge placeholder
  • clean .gitignore; no build outputs, no forge metadata

Push it anywhere with Git and the APK appears under Actions artifacts:

cd <exported-folder>
git init -b main && git add -A && git commit -m "Initial import from WebShell Forge"
gh repo create my-app --public --source . --push

In the dashboard, the same thing is the ⬇ CI-ready repo (.zip) button after scaffolding.

Development

npm test        # core unit tests (no Java needed)
npm start       # dashboard
npm run forge   # CLI

Layout:

webshell-forge/
β”œβ”€β”€ .github/workflows/ci.yml   CI: unit tests + E2E sample APK build (artifact upload)
β”œβ”€β”€ templates/
β”‚   β”œβ”€β”€ .template-version      pinned s17labs/webshell SHA + vendored date
β”‚   └── webshell/              full vendored template (the build substrate)
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ core/src/
β”‚   β”‚   β”œβ”€β”€ scaffold.js        copy template β†’ staging dir
β”‚   β”‚   β”œβ”€β”€ stamp.js           applicationId/version/app_name rewriting
β”‚   β”‚   β”œβ”€β”€ icons.js           image β†’ adaptive launcher icons (sharp)
β”‚   β”‚   β”œβ”€β”€ www.js             assets/www assembly + bridge.js injection
β”‚   β”‚   β”œβ”€β”€ build.js           gradlew runner + APK collection
β”‚   β”‚   β”œβ”€β”€ export.js          CI-ready repo generator
β”‚   β”‚   β”œβ”€β”€ zip.js             dependency-free zip writer/reader
β”‚   β”‚   β”œβ”€β”€ doctor.js          JDK/SDK environment checks
β”‚   β”‚   └── index.js           public API (createApp, buildApp, …)
β”‚   β”œβ”€β”€ dashboard/             Express server + zero-dependency browser UI
β”‚   └── cli/                   @clack/prompts wizard (bin: forge)
β”œβ”€β”€ scripts/e2e-scaffold.mjs   sample app scaffolder (npm run sample)
β”œβ”€β”€ test/run.js                node:test suite (no Java needed)
└── projects/  dist/           local outputs (gitignored)

Updating the vendored template

git -C templates/webshell pull   # or re-copy from a fresh clone
git rev-parse HEAD > new sha     # update templates/.template-version
npm test                         # stamping patterns are drift-checked by tests

License

MIT Β© s17 Labs. The vendored templates/webshell retains its own MIT license.

About

πŸ”¨ WebShell Forge β€” Turn plain HTML, CSS, and JS into native Android APKs locally. Form or CLI in, installable app out.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages