Skip to main content

Development

This guide covers setting up a development environment, building from source, and contributing to File Mover Express.

Prerequisites​

ToolMinimum VersionNotes
Go1.25CLI daemon and the Wails desktop app
Node.js22GUI (Angular) and workspace tooling
GitAnySource control
Task3Build runner — every build/test/lint target is a Task
Wails CLI (wails3)v3 (alpha)Builds the desktop app and generates frontend bindings
golangci-lintLatestGo linter

The build is driven by Task (Taskfile.yml at the repo root plus a Taskfile.yml in each src/* package). The npm run * scripts are thin wrappers that call Task, so you can use either task <name> or npm run <name>.

Install the Wails v3 CLI with:

go install github.com/wailsapp/wails/v3/cmd/wails3@latest

macOS​

brew install go node git go-task golangci-lint

Linux (Ubuntu/Debian)​

sudo apt update
sudo apt install -y nodejs npm git

Install Go from go.dev/dl (the golang-go apt package is often behind), Task by following the Task install guide, and golangci-lint by following the official guide — the apt versions are frequently outdated. Building the desktop app on Linux also requires the Wails system dependencies (GTK/WebKit); see the Wails Linux prerequisites.

Windows​

winget install GoLang.Go OpenJS.NodeJS Git.Git Task.Task

Install golangci-lint by following the official guide.


Architecture​

filemoverexpress/
├── src/
│ ├── cli/ # Go CLI daemon and backend services
│ ├── gui/ # Angular GUI application (Wails frontend)
│ ├── wails/ # Wails 3 desktop app (Go); embeds the GUI and the daemon
│ ├── protobuf/ # Protocol buffer definitions (buf)
│ └── windows-daemon-launcher/ # Windows daemon launcher helper
├── Taskfile.yml # Root build orchestration (Task)
├── docs/ # Documentation
├── CONTRIBUTING.md # Contribution guidelines
├── SECURITY.md # Security policy
└── README.md # Project overview

The desktop application is built with Wails 3: src/wails/ is a Go app that embeds the Angular GUI from src/gui/ as its frontend and compiles the transfer daemon into the same binary. The standalone filemoverexpress CLI in src/cli/ is still built and used for scripting and headless operation.


Building from Source​

task build runs the build in the correct order — CLI, GUI, and the Wails desktop app.

git clone https://github.com/awslabs/filemoverexpress.git
cd filemoverexpress
npm install
task generate # generate protobuf + Wails bindings (first build only, or after proto/Go changes)
task build

Build outputs land in dist/ (CLI binaries) and src/wails/build/bin/ (the desktop app). The npm run * scripts (e.g. npm run build) are thin wrappers around these tasks if you prefer npm.

Tip: Task caches by input checksums, so re-running task build only rebuilds what changed. On a corporate/VPN network where proxy.golang.org is blocked, prefix Go builds with GOPROXY=direct (see Troubleshooting below).

Individual build steps​

If you need to run steps individually:

# Generate all code (protobuf + Wails bindings)
task generate

# Generate protobuf code only (Go + TypeScript)
task proto:generate

# Build the CLI only (auto-detects your OS and architecture)
task cli:build

# Build the GUI only
task gui:build

# Build the Wails desktop app
task wails:build

Running tests​

task test # Run all tests (CLI, Wails, GUI)
task cli:test # Go CLI unit tests
task test:wails # Wails (Go) tests
task gui:test # GUI unit tests (Vitest, via ng test)

The GUI test suite runs on Vitest (it replaced Karma). task gui:test invokes ng test --watch=false --coverage.

Linting​

task lint # Lint all code (CLI + GUI)
task cli:lint # golangci-lint on Go code
task gui:lint # ESLint on TypeScript/Angular code

Cleaning build artifacts​

task clean # Remove build artifacts and generated code

Available Commands​

Task is the primary interface; most targets have a matching npm run wrapper.

Tasknpm wrapperDescription
task buildnpm run buildBuild CLI, GUI, and the Wails desktop app
task generate—Generate all code (protobuf + Wails bindings)
task proto:generatenpm run build:protoGenerate protobuf code only (Go + TypeScript)
task cli:buildnpm run build:cliBuild CLI for current platform
task gui:buildnpm run build:guiBuild GUI production bundle
task wails:buildnpm run build:wailsBuild the Wails desktop app
task testnpm run testRun all tests
task cli:testnpm run test:cliRun CLI unit and integration tests
task test:wailsnpm run test:wails*Run Wails (Go) tests
task gui:testnpm run test:guiRun GUI unit tests via Vitest
task lintnpm run lintLint all code
task dev—Run the desktop app in hot-reload dev mode (wails3 dev)
task clean—Remove all build artifacts and generated code

* npm run test:wails currently maps to a non-existent task wails:test in package.json; use task test:wails until that wrapper is fixed.

Run task --list to see every available target.


Environment Variables​

VariableDescriptionDefault
BUILD_VERSIONVersion stamped into the built binaries0.0.0-local-dev
GOPROXYSet to direct if proxy.golang.org is blocked on your networkGo default

Desktop Development​

To run the full desktop app with hot reload (frontend + Go backend):

task dev

This runs wails3 dev, which rebuilds and reloads the app as you edit the Go or Angular code.

GUI-only in a browser​

If you're working on the Angular GUI and want to iterate in a browser instead:

npm run --prefix src/gui start

This runs ng serve and serves the GUI at http://localhost:4200. You'll need the CLI daemon running separately (filemoverexpress daemon) for the GUI to connect to.

Note: When serving in a browser, you may need to add http://localhost:4200 to the allowed_origins list in your configuration file for CORS to work during development. The packaged Wails app uses its own webview origin and does not need this. See Configuration for details.


Development Workflow​

  1. Fork the repository
  2. Create a feature branch: feat/my-feature or fix/my-fix
  3. Make changes and ensure all tests pass
  4. Follow the guidelines in CONTRIBUTING.md
  5. Submit a pull request with a clear description of changes

Troubleshooting​

task generate / task proto:generate fails with "no such host" or DNS error On corporate or VPN networks, proxy.golang.org may be blocked:

export GOPROXY=direct
task generate # or: task proto:generate for protobuf only

protoc-gen-go or wails3 not found The proto step installs the protobuf plugins automatically. If it still fails, ensure go is on your PATH and your Go version is 1.25 or higher (go version), and that $(go env GOPATH)/bin is on your PATH so the generated-code plugins and the wails3 CLI are found.

Go version too old (Linux) The golang-go apt package is often behind. Install Go directly from go.dev/dl instead.

Permission denied on Linux/macOS binary

chmod +x ./dist/filemoverexpress-*

For more help, see the Troubleshooting guide or open an issue on GitHub.