|
1 |
| -# Hello Wasm World! |
2 |
| - |
3 |
| -## Introduction |
4 |
| - |
5 |
| -This example walks through how to compile a *hello world* executable written in C++ to [WebAssembly](https://webassembly.org/) and how to execute it with standalone WebAssembly runtimes, the Node.js JavaScript runtime, and web browser runtimes! |
6 |
| - |
7 |
| -Before getting started, make sure [Node.js](https://nodejs.org/en/download/) and [Podman (recommended)](https://podman.io/docs/installation) or [Docker](https://docs.docker.com/install/) are installed. On Linux, make sure you can run [`podman` or `docker` without `sudo`](https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo). On Windows, we highly recommend [Podman](https://podman.io/docs/installation). |
8 |
| - |
9 |
| -While we recommend following along step-by-step, the complete example can also be found in the [`examples/` directory of the project repository](https://github.com/InsightSoftwareConsortium/ITK-Wasm/tree/main/examples/hello-world). |
10 |
| - |
11 |
| -Let's get started! 🚀 |
12 |
| - |
13 |
| -## Write the code |
14 |
| - |
15 |
| -First, let's create a new directory to house our project. |
16 |
| - |
17 |
| -```sh |
18 |
| -mkdir HelloWorld |
19 |
| -cd HelloWorld |
20 |
| -``` |
21 |
| - |
22 |
| -Let's write some code! Populate *hello.cxx* with our Hello World program: |
23 |
| - |
24 |
| -```cpp |
25 |
| -#include <iostream> |
26 |
| - |
27 |
| -int main() { |
28 |
| - std::cout << "Hello Wasm world!" << std::endl; |
29 |
| - return 0; |
30 |
| -} |
31 |
| -``` |
32 |
| - |
33 |
| -Next, provide a [CMake](https://cmake.org/) build configuration at *CMakeLists.txt*: |
34 |
| - |
35 |
| -```cmake |
36 |
| -cmake_minimum_required(VERSION 3.16) |
37 |
| -project(HelloWorld) |
38 |
| -
|
39 |
| -add_executable(hello hello.cxx) |
40 |
| -``` |
41 |
| - |
42 |
| -## Install itk-wasm |
43 |
| - |
44 |
| -We use the `add_executable` command to build executables with itk-wasm. The [Emscripten](https://kripken.github.io/emscripten-site/) and [WASI](https://github.com/WebAssembly/wasi-sdk) toolchains along with itk-wasm build and execution configurations are contained in itk-wasm [dockcross](https://github.com/dockcross/dockcross) Docker images invoked by the itk-wasm command line interface (CLI). Note that the same code can also be built and tested with native operating system toolchains. This is useful for development and debugging. |
45 |
| - |
46 |
| -Build the program with the itk-wasm CLI, `itk-wasm`. This is shipped with the `itk-wasm` Node.js package. First install *itk-wasm* with the Node Package Manager, `npm`, the CLI that ships with Node.js. |
47 |
| - |
48 |
| -```sh |
49 |
| -# Initialize an empty project in the current directory |
50 |
| -npm init --yes |
51 |
| -npm install itk-wasm@1.0.0-b.106 |
52 |
| -``` |
53 |
| - |
54 |
| -## WASI |
55 |
| - |
56 |
| -Build the project with the WASI `itkwasm/wasi` toolchain in the `./wasi-build/` directory: |
57 |
| - |
58 |
| -```sh |
59 |
| -npx itk-wasm -i itkwasm/wasi build |
60 |
| -``` |
61 |
| - |
62 |
| -A `hello.wasi.wasm` WebAssembly binary is built in the `./wasi-build/` directory. |
63 |
| - |
64 |
| -```sh |
65 |
| -❯ ls wasi-build |
66 |
| -build.ninja CMakeFiles libwasi-exception-shim.a |
67 |
| -cmake_install.cmake hello.wasi.wasm |
68 |
| -``` |
69 |
| - |
70 |
| -Execute the binary with the `run` `itk-wasm` subcommand. |
71 |
| - |
72 |
| -```sh |
73 |
| -❯ npx itk-wasm run wasi-build/hello.wasi.wasm |
74 |
| -Hello Wasm world! |
75 |
| -``` |
76 |
| - |
77 |
| -Congratulations! You just executed a C++ program compiled to WebAssembly. 🎉 |
78 |
| - |
79 |
| -The binary can also be executed with other [WASI runtimes](https://github.com/mbasso/awesome-wasm#non-web-embeddings). |
80 |
| - |
81 |
| -## Node.js |
82 |
| - |
83 |
| -For Node.js or the Browser, build the project with the default [Emscripten](https://emscripten.org/) toolchain. The project is built in the `./emscripten-build` directory by default. |
84 |
| - |
85 |
| -```sh |
86 |
| -npx itk-wasm build |
87 |
| -``` |
88 |
| - |
89 |
| -To execute the project, create an `index.mjs` JavaScript file to [invoke the module](../api/node_pipelines.html): |
90 |
| - |
91 |
| -```js |
92 |
| -import path from 'path' |
93 |
| -import { runPipelineNode } from 'itk-wasm' |
94 |
| - |
95 |
| -const pipelinePath = path.resolve('emscripten-build', 'hello') |
96 |
| -const args = [] |
97 |
| -await runPipelineNode(pipelinePath, args) |
98 |
| -``` |
99 |
| - |
100 |
| -**Important**: Inside the *package.json* file, we must also add `"type": "module",` to tell Node.js that we have a modern JavaScript project that uses [ES modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules). |
101 |
| - |
102 |
| -And run it! |
103 |
| - |
104 |
| -```sh |
105 |
| -❯ npx node ./index.mjs |
106 |
| -Hello Wasm world! |
107 |
| -``` |
108 |
| - |
109 |
| -Congratulations! You just executed a C++ program in JavaScript. 🎉 |
110 |
| - |
111 |
| -## Browser |
112 |
| - |
113 |
| -The same Emscripten Wasm module can be executed in a web browser. |
114 |
| - |
115 |
| -Create an HTML file named `index.html` that will call the Wasm module through JavaScript and display its output in the HTML DOM: |
116 |
| - |
117 |
| -```html |
118 |
| -<!DOCTYPE html> |
119 |
| -<html> |
120 |
| - <head> |
121 |
| - <title>itk-wasm Browser Hello World!</title> |
122 |
| - <meta charset="UTF-8" /> |
123 |
| - <script src="https://cdn.jsdelivr.net/npm/itk-wasm@1.0.0-b.106/dist/umd/itk-wasm.min.js"></script> |
124 |
| - </head> |
125 |
| - |
126 |
| - <body> |
127 |
| - <textarea readonly>WebAssembly output...</textarea> |
128 |
| - |
129 |
| - <script> |
130 |
| - const outputTextArea = document.querySelector("textarea"); |
131 |
| - outputTextArea.textContent = "Loading..."; |
132 |
| -
|
133 |
| - const wasmURL = new URL('emscripten-build/hello', document.location) |
134 |
| - const args = [] |
135 |
| - const inputs = null |
136 |
| - const outputs = null |
137 |
| - itk.runPipeline(null, wasmURL, args, inputs, outputs).then( |
138 |
| - ({ stdout, webWorker }) => { |
139 |
| - webWorker.terminate() |
140 |
| - outputTextArea.textContent = stdout |
141 |
| - }) |
142 |
| - </script> |
143 |
| - </body> |
144 |
| -</html> |
145 |
| -``` |
146 |
| - |
147 |
| -Serve the web page and Wasm module with an http server: |
148 |
| - |
149 |
| -```sh |
150 |
| -npm install http-server |
151 |
| -http-server . |
152 |
| -``` |
153 |
| - |
154 |
| -And point your browser to `http://127.0.0.1:8080/`. |
155 |
| - |
156 |
| - |
157 |
| - |
158 |
| -Congratulations! You just executed a C++ program in your web browser. 🎉 |
| 1 | +# Hello Wasm World! |
| 2 | + |
| 3 | +## Introduction |
| 4 | + |
| 5 | +This example walks through how to compile a *hello world* executable written in C++ to [WebAssembly](https://webassembly.org/) and how to execute it with standalone WebAssembly runtimes, the Node.js JavaScript runtime, and web browser runtimes! |
| 6 | + |
| 7 | +**Updated for create-itk-wasm**: This tutorial now demonstrates the modern ITK-Wasm development workflow using the `create-itk-wasm` CLI tool, which provides a complete development environment with automated build configurations, testing infrastructure, and language binding generation. |
| 8 | + |
| 9 | +Before getting started, make sure [Node.js](https://nodejs.org/en/download/) and [Docker](https://docs.docker.com/install/) or [Podman](https://podman.io/docs/installation) are installed. On Linux, make sure you can run [`docker` without `sudo`](https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo). |
| 10 | + |
| 11 | +While we recommend following along step-by-step, the complete example can also be found in the [`examples/` directory of the project repository](https://github.com/InsightSoftwareConsortium/ITK-Wasm/tree/main/examples/hello-world). |
| 12 | + |
| 13 | +Let's get started! 🚀 |
| 14 | + |
| 15 | +## Create the project |
| 16 | + |
| 17 | +The easiest way to get started with ITK-Wasm is using the `create-itk-wasm` CLI tool, which scaffolds a complete development environment with all necessary build configurations and toolchains. |
| 18 | + |
| 19 | +First, make sure [Node.js](https://nodejs.org/en/download/) and [Docker](https://docs.docker.com/install/) or [Podman](https://podman.io/docs/installation) are installed. On Linux, make sure you can run [`docker` without `sudo`](https://askubuntu.com/questions/477551/how-can-i-use-docker-without-sudo). |
| 20 | + |
| 21 | +Create a new project: |
| 22 | + |
| 23 | +```sh |
| 24 | +npx create-itk-wasm hello-world |
| 25 | +cd hello-world |
| 26 | +``` |
| 27 | + |
| 28 | +This creates a complete project structure with: |
| 29 | +- **Native C++ build** - Traditional compiled executables for development and testing |
| 30 | +- **Emscripten toolchain** - WebAssembly compilation for browser environments |
| 31 | +- **WASI toolchain** - WebAssembly System Interface for server-side execution |
| 32 | +- **Language bindings** - Automatic TypeScript and Python wrapper generation |
| 33 | +- **Testing infrastructure** - Example tests for all target platforms |
| 34 | + |
| 35 | +## Write the code |
| 36 | + |
| 37 | +The `create-itk-wasm` tool generates a pipeline template. Let's modify it to create our Hello World program. Edit the generated C++ file in the pipeline directory (e.g., `hello-world/hello-world.cxx`): |
| 38 | + |
| 39 | +```cpp |
| 40 | +#include "itkPipeline.h" |
| 41 | +#include "itkOutputTextStream.h" |
| 42 | +#include <iostream> |
| 43 | + |
| 44 | +int main(int argc, char * argv[]) |
| 45 | +{ |
| 46 | + itk::wasm::Pipeline pipeline("hello", "A simple hello world pipeline", argc, argv); |
| 47 | + |
| 48 | + // Add an optional message parameter |
| 49 | + std::string message = "Hello Wasm world!"; |
| 50 | + pipeline.add_option("--message", message, "Message to display"); |
| 51 | + |
| 52 | + // Add text output for the message |
| 53 | + itk::wasm::OutputTextStream textOutput; |
| 54 | + pipeline.add_option("text-output", textOutput, "Text output")->required()->type_name("OUTPUT_TEXT"); |
| 55 | + |
| 56 | + ITK_WASM_PARSE(pipeline); |
| 57 | + |
| 58 | + // Output the message to both stdout and the text output stream |
| 59 | + std::cout << message << std::endl; |
| 60 | + |
| 61 | + textOutput.Get() << message << std::endl; |
| 62 | + |
| 63 | + return EXIT_SUCCESS; |
| 64 | +} |
| 65 | +``` |
| 66 | +
|
| 67 | +The ITK-Wasm pipeline structure provides: |
| 68 | +- **CLI11 integration** for robust command-line argument parsing |
| 69 | +- **Standardized I/O** through the `itk::wasm::Pipeline` interface |
| 70 | +- **Cross-platform compatibility** with the same code running natively and in WebAssembly |
| 71 | +
|
| 72 | +## Project structure |
| 73 | +
|
| 74 | +The `create-itk-wasm` tool generates a complete project structure: |
| 75 | +
|
| 76 | +``` |
| 77 | +hello-world/ |
| 78 | +├── pixi.toml # Pixi environment and task configuration |
| 79 | +├── package.json # Node.js dependencies and scripts |
| 80 | +├── CMakeLists.txt # Main CMake configuration |
| 81 | +├── hello/ # Pipeline directory |
| 82 | +│ ├── hello.cxx # Pipeline C++ source code |
| 83 | +│ └── CMakeLists.txt # Pipeline-specific CMake config |
| 84 | +├── tests/ # Test files |
| 85 | +├── index.html # Browser demo page |
| 86 | +├── index.mjs # Node.js example |
| 87 | +└── README.md # Project documentation |
| 88 | +``` |
| 89 | +
|
| 90 | +This structure supports: |
| 91 | +- **Multiple pipelines** - Add more pipelines as subdirectories |
| 92 | +- **Automatic binding generation** - TypeScript and Python wrappers are generated |
| 93 | +- **Comprehensive testing** - Native, WASI, Node.js, and browser tests |
| 94 | +- **Modern tooling** - Pixi for dependency management, pnpm for JavaScript packages |
| 95 | +
|
| 96 | +## Build and run |
| 97 | +
|
| 98 | +The generated project includes [pixi](https://pixi.sh/) for seamless dependency management and build orchestration. Pixi handles the installation of all required toolchains and provides consistent commands across platforms. |
| 99 | +
|
| 100 | +### WASI |
| 101 | +
|
| 102 | +Build and test the WASI WebAssembly binary: |
| 103 | +
|
| 104 | +```sh |
| 105 | +pixi run build:wasi |
| 106 | +pixi run test:wasi |
| 107 | +``` |
| 108 | + |
| 109 | +This creates a `hello.wasi.wasm` binary that can be executed with WASI runtimes. |
| 110 | + |
| 111 | +```sh |
| 112 | +❯ pixi run test:wasi |
| 113 | +Hello Wasm world! |
| 114 | +``` |
| 115 | + |
| 116 | +## Next steps |
| 117 | + |
| 118 | +Now that you have a working ITK-Wasm pipeline, you can: |
| 119 | + |
| 120 | +1. **Add more functionality** - Modify the C++ code to perform image processing, analysis, or other computational tasks |
| 121 | +2. **Add inputs and outputs** - Use `create-itk-wasm` again to add more pipelines or modify the existing one to handle images, meshes, or other data types |
| 122 | +3. **Integrate with your application** - Use the generated TypeScript or Python bindings to integrate your pipeline into web applications, desktop software, or data analysis workflows |
| 123 | +4. **Publish your package** - Share your pipeline with the community by publishing it as an npm package or Python package |
| 124 | + |
| 125 | +For more advanced examples and comprehensive documentation, visit [wasm.itk.org](https://wasm.itk.org). |
| 126 | + |
| 127 | +Consider adding your project to the [ITK-Wasm packages list](https://wasm.itk.org/en/latest/introduction/packages.html) to help others discover your work! |
| 128 | + |
| 129 | +The binary can also be executed with other [WASI runtimes](https://github.com/mbasso/awesome-wasm#non-web-embeddings). |
| 130 | + |
| 131 | +## Node.js |
| 132 | + |
| 133 | +Build and test with Node.js: |
| 134 | + |
| 135 | +```sh |
| 136 | +pixi run build:emscripten |
| 137 | +pixi run test:node |
| 138 | +``` |
| 139 | + |
| 140 | +This builds the Emscripten WebAssembly module and tests it in Node.js using the generated TypeScript bindings. |
| 141 | + |
| 142 | +```sh |
| 143 | +❯ pixi run test:node |
| 144 | +Hello Wasm world! |
| 145 | +``` |
| 146 | + |
| 147 | +The `create-itk-wasm` tool automatically generates TypeScript bindings that provide a clean, type-safe API for calling your pipeline from JavaScript/TypeScript. |
| 148 | + |
| 149 | +## Browser |
| 150 | + |
| 151 | +The same Emscripten WebAssembly module can be executed in a web browser using the generated web examples. |
| 152 | + |
| 153 | +Start the development server: |
| 154 | + |
| 155 | +```sh |
| 156 | +pixi run start |
| 157 | +``` |
| 158 | + |
| 159 | +Then open your browser to the URL shown (typically `http://localhost:8080`) to see the pipeline running in the browser. |
| 160 | + |
| 161 | + |
| 162 | + |
| 163 | +The `create-itk-wasm` tool generates complete web examples demonstrating how to use your pipeline in browser environments. |
| 164 | + |
| 165 | +## Native development |
| 166 | + |
| 167 | +For development and debugging, you can also build and run the pipeline natively: |
| 168 | + |
| 169 | +```sh |
| 170 | +pixi run build:native |
| 171 | +pixi run test:native |
| 172 | +``` |
| 173 | + |
| 174 | +This builds a traditional C++ executable that can be debugged with standard tools like `gdb` or IDE debuggers. |
| 175 | + |
| 176 | +## Next steps |
| 177 | + |
| 178 | +Now that you have a working ITK-Wasm pipeline, you can: |
| 179 | + |
| 180 | +1. **Add more functionality** - Modify the C++ code to perform image processing, analysis, or other computational tasks |
| 181 | +2. **Add inputs and outputs** - Use `create-itk-wasm` again to add more pipelines or modify the existing one to handle images, meshes, or other data types |
| 182 | +3. **Integrate with your application** - Use the generated TypeScript or Python bindings to integrate your pipeline into web applications, desktop software, or data analysis workflows |
| 183 | +4. **Publish your package** - Share your pipeline with the community by publishing it as an npm package or Python package |
| 184 | + |
| 185 | +For more advanced examples and comprehensive documentation, visit [wasm.itk.org](https://wasm.itk.org). |
| 186 | + |
| 187 | +Consider adding your project to the [ITK-Wasm packages list](https://wasm.itk.org/en/latest/introduction/packages.html) to help others discover your work! |
0 commit comments