This tutorial shows you how to test your jDeploy applications locally during development using the jdeploy install command. You’ll learn how to install, run, and debug your app on your development machine exactly as users will experience it — with native launchers, CLI commands, file associations, and all other features — without publishing to npm or GitHub.
Introduction
Why Local Testing Matters
When developing desktop applications with jDeploy, you need to verify that everything works correctly before publishing. This includes:
-
GUI applications launching properly with the right icons and splash screens
-
CLI commands being accessible from the terminal
-
File associations opening your app when users click specific file types
-
URL schemes (deep linking) routing correctly
-
Background services starting and stopping as expected
-
MCP servers integrating with AI tools like Claude Code
-
Auto-update mechanisms detecting new versions
Traditionally, testing these features required publishing to npm or GitHub, then installing the published version. This created a slow feedback loop: make a change, publish, install, test, repeat.
With jdeploy install, you can test the complete installation experience locally in seconds, not minutes.
What is Local Installation?
Local installation uses jDeploy’s headless installer to install your app directly from your project directory. The installer:
-
Packages your application into the jDeploy bundle format
-
Generates all platform-specific launchers and metadata
-
Installs the app to your system exactly as end users would experience it
-
Configures PATH entries, file associations, and all other features
The installed app runs from ~/.jdeploy/apps (or %USERPROFILE%\.jdeploy\apps on Windows), just like apps installed from npm or GitHub. The only difference is that it points to your local project directory for the application bundle and configuration.
Local Install vs. npm link
jDeploy previously supported npm link for local testing, which is still available via jdeploy install --npm. However, the new default local installation method provides significant advantages:
| Feature | npm link (Legacy) |
jdeploy install (Default) |
|---|---|---|
Native launchers |
No (requires |
Yes (full .app, .exe, etc.) |
CLI commands |
Via |
Installed to PATH |
File associations |
Not supported |
Fully supported |
Background services |
Not supported |
Fully supported |
MCP server integration |
Not supported |
Fully supported with |
Testing as user sees it |
Different experience |
Identical to production |
Installation speed |
Very fast |
Fast (a few seconds) |
For most development workflows, jdeploy install provides a much more accurate testing environment.
Prerequisites
Before starting, ensure you have:
-
jDeploy 6.0 or later installed (download)
-
A jDeploy project set up with a
package.jsonfile -
Your app built (e.g.,
mvn packageorgradle buildcompleted)
| If you don’t have a project yet, create one using the jDeploy Desktop App by selecting "Import Project" or "Create New Project" from the main menu. |
Basic Usage
Installing Your App Locally
Navigate to your project directory (the one containing package.json) and run:
jdeploy install
You’ll see output similar to:
Starting local installation...
Packaging application...
Creating jdeploy bundle...
Generating local jdeploy-files...
Generated jdeploy-files at: /path/to/project/jdeploy/.jdeploy-files
Running headless installer...
Installing MyApp...
Installing launchers...
Installing CLI commands...
Updating PATH...
Local installation completed successfully!
That’s it! Your app is now installed and ready to use.
Verifying the Installation
After installation, verify that everything works:
1. Launch the GUI App
On macOS:
open ~/Applications/MyApp.app
Or search for "MyApp" in Spotlight and launch it.
On Windows: Look for "MyApp" in the Start Menu, or run:
%USERPROFILE%\.jdeploy\apps\myapp\MyApp.exe
On Linux: Check your application menu, or run:
~/.jdeploy/apps/myapp/MyApp
2. Test CLI Commands
If your app includes CLI commands (defined in package.json under jdeploy.commands), they should be available in your PATH:
myapp-cli --version
You may need to restart your terminal or run source ~/.zshrc (macOS/Linux) to pick up PATH changes.
|
3. Check File Associations
If you configured file associations in jDeploy, try opening a file of that type:
# Example: if your app handles .mydata files
open test.mydata # macOS
start test.mydata # Windows
xdg-open test.mydata # Linux
Your app should launch and open the file.
Updating After Code Changes
When you make changes to your code:
-
Rebuild your project (
mvn package,gradle build, etc.) -
Reinstall with
jdeploy install
The installer will update the existing installation in place. You don’t need to uninstall first.
# Make changes to your code
mvn clean package
# Reinstall
jdeploy install
Always rebuild your project before running jdeploy install, or the installer will package the old jar file.
|
Advanced Features
Running Your App with jdeploy run
Instead of manually launching your app after installation, use jdeploy run:
jdeploy run
This launches the installed GUI application directly. If your app isn’t installed yet, you’ll see:
Application is not installed locally.
Run 'jdeploy install' first, or use --install flag.
You can combine installation and running in one command:
jdeploy run --install
This will:
1. Run jdeploy install if needed
2. Launch the installed app
Running CLI Commands
If your app has CLI commands, you can run them with arguments:
jdeploy run mycommand -- arg1 arg2 arg3
The -- delimiter separates jDeploy’s options from your command’s arguments.
Example with the --install flag:
jdeploy run --install mycommand -- --input data.txt --output result.txt
This is useful in build scripts or CI environments where you want to ensure the latest version is installed before running.
Debugging with jdeploy debug
The jdeploy debug command launches your app with Java remote debugging enabled, allowing you to attach a debugger from your IDE.
Debug the GUI App
jdeploy debug
This launches your app with the Java Debug Wire Protocol (JDWP) enabled on port 5005 (default), waiting for a debugger to attach.
You’ll see output like:
Listening for transport dt_socket at address: 5005
Now attach your IDE’s debugger to localhost:5005.
Custom Debug Port
Change the port with the --port flag:
jdeploy debug --port=8000
Debug Without Suspending
By default, the app waits for the debugger before starting. To start immediately:
jdeploy debug --no-suspend
Debug CLI Commands
Debug a specific CLI command:
jdeploy debug mycommand -- arg1 arg2
With custom port and no suspend:
jdeploy debug --port=8000 --no-suspend mycommand -- --input data.txt
Debug with Auto-Install
Combine installation and debugging:
jdeploy debug --install --port=5006
Configuring AI Tools (MCP Servers)
If your app includes MCP servers for AI tool integration (like Claude Code, Cursor, etc.), you can configure them during local installation with the --ai-tools flag.
jdeploy install --ai-tools=claude-code,cursor,claude-desktop
This will:
1. Install your app locally
2. Configure the specified AI tools to recognize your MCP server
3. Update the AI tool configuration files (e.g., ~/Library/Application Support/Claude/claude_desktop_config.json on macOS)
Supported AI tools:
-
claude-code- Claude Code (Anthropic’s coding agent) -
claude-desktop- Claude Desktop app -
cursor- Cursor IDE -
codex-cli- OpenAI Codex CLI -
gemini-cli- Google Gemini CLI
You can specify one or more tools as a comma-separated list.
| After installation, restart your AI tool to pick up the new MCP server configuration. |
Using Legacy npm link Behavior
If you prefer the old npm link behavior, use the --npm flag:
jdeploy install --npm
This will:
1. Package the application
2. Run npm link to symlink it
You can then run your app with npx:
npx myapp
The --npm flag is primarily for backward compatibility. For most development workflows, the default local installation provides a better testing experience.
|
Testing Multi-Modal Applications
jDeploy 6.0 supports multi-modal applications that combine GUI apps, CLI commands, background services, and MCP servers in a single package. Local installation makes it easy to test all these components together.
Example: Note Manager with MCP Server
Imagine a note-taking app with:
-
A JavaFX GUI for managing notes
-
A CLI command
notesfor quick command-line access -
An MCP server
notes-mcpfor AI tool integration
The package.json might look like:
{
"name": "note-manager",
"version": "1.0.0",
"jdeploy": {
"jar": "target/note-manager.jar",
"title": "Note Manager",
"commands": {
"notes": {
"mainClass": "com.example.notes.NotesCommand"
},
"notes-mcp": {
"mainClass": "com.example.notes.McpServer",
"mcpServers": {
"notes-mcp": {}
}
}
}
}
}
Testing the GUI
jdeploy install
jdeploy run
Or directly:
open ~/Applications/Note\ Manager.app # macOS
Testing the CLI Command
notes list
notes create "My First Note"
notes search "first"
Testing the MCP Server
# Install with AI tool configuration
jdeploy install --ai-tools=claude-code
# Restart Claude Code
# Now in Claude Code:
# "Create a new note called 'Meeting Notes' with the content 'Discussed Q1 roadmap'"
The MCP server should receive the request and create the note in your app.
Debugging Multi-Modal Apps
Debug different components:
# Debug the GUI
jdeploy debug
# Debug the CLI command
jdeploy debug notes -- create "Test"
# Debug the MCP server
jdeploy debug notes-mcp
For the MCP server, you’ll also need to restart your AI tool after attaching the debugger, as it communicates via stdin/stdout.
Workflow Integration
IDE Integration
Most IDEs can be configured to run jDeploy commands as build tasks.
IntelliJ IDEA
Create a run configuration:
-
Run > Edit Configurations…
-
Click + and select Shell Script
-
Set Script text to:
#!/bin/bash cd $PROJECT_DIR mvn clean package && jdeploy install -
Name it "Build & Install Locally"
-
Click OK
Now you can rebuild and reinstall with one click or keyboard shortcut.
VS Code
Add a task to .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build and Install Locally",
"type": "shell",
"command": "mvn clean package && jdeploy install",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": []
}
]
}
Run with Terminal > Run Build Task… or Cmd+Shift+B (macOS) / Ctrl+Shift+B (Windows/Linux).
CI/CD Testing
You can use local installation in CI pipelines to verify that your app installs correctly before publishing.
Example GitHub Actions workflow:
name: Test Local Installation
on: [push, pull_request]
jobs:
test-install:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- name: Set up Java
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
- name: Build application
run: mvn clean package
- name: Install jDeploy
run: npm install -g jdeploy
- name: Test local installation
run: jdeploy install
- name: Verify CLI commands
run: myapp-cli --version
This ensures that your app can be installed on all platforms before merging changes.
Troubleshooting
App Not Found After Install
Symptom: After running jdeploy install, you can’t find the app in your application menu or PATH.
Solutions:
-
Restart your terminal to pick up PATH changes:
# macOS/Linux source ~/.zshrc # or ~/.bashrc -
Check the installation directory:
ls -la ~/.jdeploy/apps/ # macOS/Linux dir %USERPROFILE%\.jdeploy\apps\ # Windows -
Verify package.json has a valid
namefield - this determines the app directory name.
Old Version Still Running
Symptom: After reinstalling, the app still shows old behavior.
Solutions:
-
Rebuild first:
mvn clean package # or gradle clean build jdeploy install -
Clear the jdeploy bundle:
rm -rf jdeploy-bundle jdeploy/.jdeploy-files jdeploy install -
Force-quit the app if it’s still running from the old installation.
CLI Commands Not in PATH
Symptom: After installation, CLI commands aren’t found.
Solutions:
-
Restart your terminal or source your shell config:
source ~/.zshrc # macOS/Linux with zsh source ~/.bashrc # macOS/Linux with bash -
Check your package.json defines commands correctly:
{ "jdeploy": { "commands": { "mycommand": { "mainClass": "com.example.MyCommand" } } } } -
Verify the symlink exists:
ls -la ~/.jdeploy/bin/ # macOS/Linux dir %USERPROFILE%\.jdeploy\bin\ # Windows
Installation Fails on Windows
Symptom: jdeploy install fails with permission errors on Windows.
Solutions:
-
Run as Administrator: Right-click Command Prompt or PowerShell and select "Run as Administrator"
-
Check antivirus settings: Some antivirus software blocks executables in hidden directories like
.jdeploy. Add an exception for%USERPROFILE%\.jdeploy\. -
Use a non-hidden directory: Configure
winAppDirin package.json:{ "jdeploy": { "winAppDir": "AppData\\Local\\Programs" } }
MCP Server Not Detected by AI Tool
Symptom: After jdeploy install --ai-tools=claude-code, Claude Code doesn’t see the MCP server.
Solutions:
-
Restart the AI tool completely (quit and relaunch)
-
Check the configuration file was updated:
# macOS cat ~/Library/Application\ Support/Claude/claude_desktop_config.json # Windows type %APPDATA%\Claude\claude_desktop_config.json # Linux cat ~/.config/Claude/claude_desktop_config.json -
Verify the MCP server command in package.json has
mcpServersconfiguration:{ "jdeploy": { "commands": { "my-mcp": { "mainClass": "com.example.McpServer", "mcpServers": { "my-mcp": { "description": "My MCP Server" } } } } } }
Best Practices
1. Automate Build + Install
Create a script or IDE task that combines building and installing:
#!/bin/bash
# rebuild.sh
mvn clean package && jdeploy install
Make it executable:
chmod +x rebuild.sh
Now you can just run ./rebuild.sh after making changes.
2. Test on Multiple Platforms
If you develop on macOS but deploy to Windows and Linux, use virtual machines or CI to test local installation on all platforms. The installation process differs per platform, so it’s important to verify each one.
3. Use Version Control for package.json
Always commit your package.json changes to version control. The local installation reads from this file, so if you change settings like commands, file associations, or JVM arguments, commit them before reinstalling.
4. Clean Install for Major Changes
For significant changes (like adding new commands or changing the main class), do a clean install:
rm -rf jdeploy-bundle jdeploy/.jdeploy-files
mvn clean package
jdeploy install
5. Test Uninstallation
Before publishing, verify that uninstallation works correctly. On macOS and Windows, the app installer includes an uninstall option. Test it to ensure no files are left behind.
You can also test programmatic uninstallation:
# macOS/Linux
~/.jdeploy/apps/myapp/uninstall.sh
# Windows
%USERPROFILE%\.jdeploy\apps\myapp\uninstall.bat
Real-World Example
Let’s walk through a complete development cycle for a JavaFX note-taking app.
Initial Setup
# Create project via jDeploy Desktop App
# (File > Create New Project > JavaFX Application)
cd ~/projects/note-app
mvn clean package
jdeploy install
Development Iteration
-
Add a new feature (e.g., search functionality)
-
Write tests and verify they pass
-
Rebuild and reinstall:
mvn clean package && jdeploy install -
Test the GUI:
jdeploy run -
Try the search feature in the running app
Add a CLI Command
Edit package.json:
{
"jdeploy": {
"commands": {
"notes": {
"mainClass": "com.example.notes.NotesCommand",
"description": "Command-line note manager"
}
}
}
}
Rebuild and reinstall:
mvn clean package && jdeploy install
Test the CLI:
notes --help
notes create "Test Note"
notes list
Add MCP Server for AI Integration
Update package.json:
{
"jdeploy": {
"commands": {
"notes": { ... },
"notes-mcp": {
"mainClass": "com.example.notes.McpServer",
"mcpServers": {
"notes-mcp": {
"description": "AI-controllable note manager"
}
}
}
}
}
}
Install with AI tool configuration:
mvn clean package && jdeploy install --ai-tools=claude-code
Restart Claude Code and test:
User: "Create a note called 'Meeting Notes' with the content 'Discussed Q1 roadmap'"
Debug an Issue
A user reports that searching for notes with special characters crashes the app.
-
Add a breakpoint in the search code
-
Debug the app:
jdeploy debug --install -
Attach debugger from your IDE to
localhost:5005 -
Trigger the search in the GUI
-
Step through code and identify the issue
-
Fix the bug and rebuild:
mvn clean package && jdeploy install -
Verify the fix by testing again
Prepare for Release
Before publishing to npm or GitHub:
-
Test on all platforms:
Run
jdeploy installon macOS, Windows, and Linux (via VM or CI) -
Test uninstallation:
Verify the app can be cleanly uninstalled
-
Test upgrades:
Install an old version, then reinstall the new version and verify it upgrades correctly
-
Review package.json:
Ensure all metadata is correct (version, description, homepage, etc.)
-
Publish:
jdeploy publish
Conclusion
The jdeploy install command transforms local testing from a cumbersome process into a seamless part of your development workflow. By installing your app exactly as users will experience it — complete with native launchers, CLI commands, file associations, and MCP servers — you can catch issues early and iterate quickly.
Key takeaways:
-
Use
jdeploy installas your default local testing method (notnpm link) -
Combine with
jdeploy runandjdeploy debugfor efficient development cycles -
Test multi-modal apps (GUI + CLI + MCP) together in one installation
-
Configure AI tools with
--ai-toolsto test MCP server integration -
Automate rebuilding and reinstalling in your IDE or build scripts
-
Test on all platforms before publishing
With local installation, you can confidently develop, test, and debug your jDeploy applications with the same experience your users will have.
Related Resources
-
jDeploy Developer Guide - Complete reference documentation
-
Making JavaFX Apps Scriptable via MCP - Tutorial on MCP server integration
-
Deep Linking in Swing Apps - Tutorial on URL scheme handling
-
Building CLI Apps with PicoCLI and jDeploy - Tutorial on command-line applications
Have questions? Visit the jDeploy Discussions on GitHub.