CONTRIBUTING.md
April 23, 2026 · View on GitHub
Contributing to
NetPad
Thank you for considering contributing to NetPad! We're excited to have you join the project.
- How to Contribute
- Submitting Changes
- Project Structure
- Build & Run
- Packaging
- Testing
- Code Style & Checks
- Issue Reporting
- Documentation Guidelines
- License
- Contact
- Acknowledgments
How to Contribute :star:
- Report bugs or request features through the issue tracker.
- Fork
the repository, create a branch, make your changes,
and submit
a pull request
to the
mainbranch.
Submitting Changes
- Branching Strategy: Create a branch for your work
- For new features or changes use the
feat/prefix, example:feat/my-new-feature - For bugs or fixes use the
fix/prefix, example:fix/my-fix
- For new features or changes use the
- Commit Messages: Use the imperative mood, e.g.
Add contributing guidelines. - Pull Requests: Ensure your PR includes tests and follows our coding standards. Include a small description of the changes as well as the issue number (if applicable).
Pull request example :arrow_down:
Added contributing guidelines to make it easier for new contributors to get started.
Changes Made:
- Added a new CONTRIBUTING.md file.
- Updated the README.md file to include a link to the new CONTRIBUTING.md file.
Project Structure
NetPad has a .NET backend (C#) and an Aurelia 2 TypeScript frontend. The backend handles script compilation, execution, data connections, and more, while the frontend provides the editor UI. The frontend can be hosted in different shells: a web browser, an Electron desktop app, or a Tauri native desktop app.
src/
├── Core/NetPad.Runtime # Core runtime: script execution, compilation, data connections
├── Apps/
│ ├── NetPad.Apps.App # ASP.NET Core host + SPA frontend (App/ subdirectory)
│ ├── NetPad.Apps.Common # Shared app services, CQRS handlers, EF Core data drivers
│ ├── NetPad.Apps.Cli # CLI tool (npad)
│ ├── NetPad.Apps.ScriptHost # Separate process for isolated script execution
│ ├── NetPad.Apps.Shells.Electron
│ ├── NetPad.Apps.Shells.Tauri
│ └── NetPad.Apps.Shells.Web
├── Plugins/NetPad.Plugins.OmniSharp # Code intelligence (IntelliSense, diagnostics)
└── Tests/ # Test projects mirror the main project structure
For a deeper dive into the architecture, IPC model, and startup flow, see the technical documentation.
Build & Run :hammer_and_pick:
Prerequisites
- Node v22+
- .NET SDK 9.x
- EF Core tools: install with
dotnet tool install --global dotnet-ef - (If contributing to the Tauri shell) Rust toolchain — see Tauri prerequisites for platform-specific system dependencies
- (Recommended) just command runner — a
justfileis provided with recipes for building, running, testing, and linting. Runjustto see all available tasks. If you prefer not to usejust, you can find the equivalent raw commands in thejustfileand run them directly.
Start by cloning, or forking, the repository:
git clone https://github.com/tareqimbasher/NetPad.git && cd NetPad
Then install all frontend dependencies:
just npm-install-all
Without just
npm install --prefix src/Apps/NetPad.Apps.App/App
npm install --prefix src/Apps/NetPad.Apps.App/ElectronHostHook
npm install --prefix src/Apps/NetPad.Apps.Shells.Tauri/TauriApp
Web Browser
- Run the frontend
just web-run-frontend
- Run the .NET backend
just web-run-backend
Navigate to the app from your web browser at http://localhost:57940.
Without just
# Terminal 1: Frontend
cd src/Apps/NetPad.Apps.App/App
npm run start-web
# Terminal 2: Backend
cd src/Apps/NetPad.Apps.App
dotnet watch run --environment Development
Note
Creating new SQLite database connections is not supported when NetPad is used in a browser.
Electron Desktop App
- Run the frontend
just electron-run-frontend
- Run the Electron backend
just electron-run-backend
# For ARM:
just electron-run-backend-mac-arm64
just electron-run-backend-linux-arm64
just electron-run-backend-win-arm64
Tip
You need the electron-sharp dotnet tool installed:
dotnet tool install ElectronSharp.CLI -g
Without just
# Frontend
cd src/Apps/NetPad.Apps.App/ElectronHostHook && npm install
cd ../App && npm install
npm start
# Backend
cd src/Apps/NetPad.Apps.App/
electron-sharp start /watch /manifest electron.manifest.js
# For ARM:
electron-sharp start /watch /manifest electron.manifest.js /target custom "osx-arm64;mac" /electron-arch arm64
electron-sharp start /watch /manifest electron.manifest.js /target custom "linux-arm64;linux" /electron-arch arm64
electron-sharp start /watch /manifest electron.manifest.js /target custom "win-arm64;win" /electron-arch arm64
Tip
If invoking any of those commands gives you strange errors (like .NET 6 not installed), it means you've typed electronize instead of electron-sharp.
Tip
The very first electron-sharp start is slow due to dependency downloads. Later runs are much
faster!
Tauri (Native Shell) Desktop App
You will need to have the Rust toolchain installed to build the Tauri app. See the Tauri prerequisites for platform-specific system dependencies.
- Run the .NET backend
just tauri-run-backend
- Run the Tauri frontend (in another terminal)
just tauri-run-frontend
Without just
# Terminal 1: Backend
cd src/Apps/NetPad.Apps.App
dotnet watch run --environment Development --tauri
# Terminal 2: Tauri frontend
cd src/Apps/NetPad.Apps.Shells.Tauri/TauriApp
npm install
npx tauri dev
Packaging :package:
Production packaging is automated via the GitHub Actions release workflow — see
.github/workflows/release.yml for the full CI/CD definition.
The CLI is published separately via
.github/workflows/publish-cli.yml. The sections below cover
how to build packages locally.
Web
Build a self-contained .NET app with the SPA frontend bundled in, targeting your current host OS/architecture:
just web-build-release
The output is a standalone ASP.NET Core app in src/Apps/NetPad.Apps.App/bin/publish, suitable for
distribution or deployment to any server or container.
Without just
For a framework-dependent build (smaller, but requires .NET installed on the target server):
dotnet publish src/Apps/NetPad.Apps.App -c Release /p:WebBuild=true
The /p:WebBuild=true flag tells the build to use the web webpack target instead of
electron-renderer.
Electron
The Electron app is built and packaged using
electron-builder. Configuration is in the
electron.manifest.js file.
Build for your target platform:
# For x64:
just electron-build-release-win-x64
just electron-build-release-mac-x64
just electron-build-release-linux-x64
# For ARM64:
just electron-build-release-win-arm64
just electron-build-release-mac-arm64
just electron-build-release-linux-arm64
Packaged files can be found in the bin/Desktop folder.
Note
To build flatpak files the flatpak and flatpak-builder packages need to be installed.
Without just
From the root directory of the NetPad.Apps.App project:
# For x64:
electron-sharp build /target win /manifest electron.manifest.js /PublishSingleFile false
electron-sharp build /target osx /manifest electron.manifest.js /PublishSingleFile false
electron-sharp build /target linux /manifest electron.manifest.js /PublishSingleFile false
# For ARM64:
electron-sharp build /target custom "osx-arm64;mac" /electron-arch arm64 /manifest electron.manifest.js /PublishSingleFile false
electron-sharp build /target custom "linux-arm64;linux" /electron-arch arm64 /manifest electron.manifest.js /PublishSingleFile false
electron-sharp build /target custom "win-arm64;win" /electron-arch arm64 /manifest electron.manifest.js /PublishSingleFile false
See the ElectronSharp docs for additional CLI options when packaging the app, and electron-builder for additional configuration options.
Tauri
Tauri packaging uses platform-specific config files located in
src/Apps/NetPad.Apps.Shells.Tauri/TauriApp/src-tauri/.
Each config handles the dotnet publish step automatically as a beforeBuildCommand.
Build for your target platform:
# For x64:
just tauri-build-release-win-x64
just tauri-build-release-linux-x64
just tauri-build-release-mac-x64
# For ARM64:
just tauri-build-release-win-arm64
just tauri-build-release-linux-arm64
just tauri-build-release-mac-arm64
Note
On Linux, you'll need additional system dependencies:
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
Without just
From the src/Apps/NetPad.Apps.Shells.Tauri/TauriApp directory:
# For x64:
npx tauri build -c src-tauri/tauri.conf.win-x64.json5
npx tauri build -c src-tauri/tauri.conf.linux-x64.json5
npx tauri build --target x86_64-apple-darwin -c src-tauri/tauri.conf.mac-x64.json5
# For ARM64:
npx tauri build -c src-tauri/tauri.conf.win-arm64.json5
npx tauri build -c src-tauri/tauri.conf.linux-arm64.json5
npx tauri build --target aarch64-apple-darwin -c src-tauri/tauri.conf.mac-arm64.json5
Testing :test_tube:
.NET Tests
just dotnet-test
To run a specific test by name:
dotnet test src --filter "FullyQualifiedName~ClassName.MethodName"
To run a specific test project:
dotnet test src/Tests/NetPad.Runtime.Tests
Note
Integration tests use Testcontainers (PostgreSQL) and require
Docker. They are excluded from just dotnet-test by default. To run all tests including
integration tests, use just dotnet-test-all.
JavaScript Tests
just js-test
Rust Tests
Only relevant when contributing to the Tauri shell's Rust code.
just rust-test
Run Everything
To run all tests, lints, and checks in one go:
just check-all
Without just
# .NET tests (excluding integration tests)
dotnet test src --filter "FullyQualifiedName!~IntegrationTests"
# JavaScript tests
npm test --prefix src/Apps/NetPad.Apps.App/App
# JavaScript linting
npm run lint --prefix src/Apps/NetPad.Apps.App/App
Code Style & Checks
- C#:
TreatWarningsAsErrorsis enabled globally — your code must compile without warnings. Runjust dotnet-formatto auto-format before submitting. - JavaScript/TypeScript: Run
just js-lintto check for linting issues. - Rust (Tauri shell): Run
just rust-lintto check formatting and lint Rust code, orjust rust-formatto auto-format. - Before opening a PR, run
just check-allto validate tests and linting together.
Issue Reporting
- Bug Reports: Include steps to reproduce and environment details.
- Feature Requests: Clearly describe the feature and why it's needed.
Documentation Guidelines
- User-facing documentation (features, CLI usage, data connections, troubleshooting) lives
in
docs/wiki/. - Technical documentation (architecture, IPC, startup flow, internal guides) lives
in
docs/technical-docs/. - If your change affects user-visible behavior, update the relevant docs along with your code.
License
By contributing, you agree that your contributions will be licensed under the MIT LICENSE.
Contact
If you have any questions, feel free to open an issue or contact us at our Discord Server
At our Discord, you can find the latest announcements, troubleshooting, ideas and feedback, and more.
Acknowledgments
Thank you to all who have contributed to NetPad! You can see all contributors here.