Repository: InsightSoftwareConsortium/ITK-Wasm (language: python)

Issue:
Core package

Core package

Package refactoring
Refactor into `packages/`:

1.`@itk-wasm/dicom` (currently in `dist/`), then incorporate the ./io/internal/pipelines/image/read-dicom/CMakeLists.txt
2. `@itk-wasm/image-io`
3. `@itk-wasm/mesh-io`
4. ~`@itk-wasm/polydata-io`~ - no longer supported
6. `@itk-wasm/mesh-to-polydata` (migrate to [remote module repository](https://github.com/InsightSoftwareConsortium/ITKMeshToPolyData))
7. Migrate `src/core` -> `itk-wasm`

Then consolidate duplication when possible, e.g. *BuildZstd.cmake*.

Then configuration as a npm/pnpm workspace.


Discussion / hints:
Closes #662 
Closes #662 
1. addressed via #828 
2. partially addressed via #741 
3. partially addressed via https://github.com/InsightSoftwareConsortium/itk-wasm/pull/1009
6. partially addressed in https://github.com/InsightSoftwareConsortium/ITKMeshToPolyData/pull/59
7. and pnpm workspace partially addressed in https://github.com/InsightSoftwareConsortium/itk-wasm/pull/1010

Fix patch:
diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md
index 5ee22dd09..c78a243a3 100644
--- a/BREAKING_CHANGES.md
+++ b/BREAKING_CHANGES.md
@@ -10,6 +10,28 @@ For a log and guide when transitioning from itk.js to itk-wasm,
 please see [the migration
 guide](doc/content/docs/itk_js_to_itk_wasm_migration_guide.md).
 
+## From 1.0.0-b.158 to 1.0.0-b.159
+
+- itkConfig.js as been replaced by run-time configuration via setPipelineWorkerUrl, setPipelinesBaseUrl
+- readDICOMTags has been migrated to @itk-wasm/dicom and as readDicomTags
+- readDICOMTagsArrayBuffer has been migrated to @itk-wasm/dicom and as readDicomTags
+- readDICOMTagsLocalFile has been migrated to @itk-wasm/dicom and as readDicomTagsNode
+- readImageDICOMFileSeries has been migrated to @itk-wasm/dicom as readImageDicomFileSeries
+- readImageDICOMArrayBufferSeries has been migrated to @itk-wasm/dicom as readImageDicomFileSeries
+- readImageLocalDICOMFileSeries has been migrated to @itk-wasm/dicom as readImageDicomFileSeriesNode
+- meshToPolyData, meshToPolyDataNode, polyDataToMesh, polyDataToMeshNode have been migrated to @itk-wasm/mesh-to-poly-data
+- High level IO function have been removed: readArrayBuffer, readBlob, readFile, readLocalFile, writeLocalFile
+- readImageArrayBuffer has been migrated to @itk-wasm/image-io as readImageFile
+- readImageBlob has been migrated to @itk-wasm/image-io as readImageFile
+- readImageFile has been migrated to @itk-wasm/image-io as readImageFile
+- readImageFileSeries has been migrated to @itk-wasm/image-io readImageFileSeries
+- readImageLocalFile has been migrated to @itk-wasm/image-io readImageFileNode
+- readMeshArrayBuffer has been migrated to @itk-wasm/mesh-io readMeshFile
+- readMeshFile has been migrated to @itk-wasm/mesh-io readMeshFile
+- readMeshLocalFile has been migrated to @itk-wasm/mesh-io readMeshFileNode
+- writeImageArrayBuffer has been migrated to @itk-wasm/image-io writeImageFile
+- writeImageLocalFile has been migrated from @itk-wasm/image-io writeImageFileNode
+
 ## From 1.0.0-b.101 to 1.0.0-b.102
 
 - apply-presentation-state-to-dicom-image does not take dicom image out flag: was not supported
diff --git a/dist/polydata-io/index.js b/dist/polydata-io/index.js
deleted file mode 100644
index a148c1fe1..000000000
--- a/dist/polydata-io/index.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const PolyDataIOIndex = [
-  'VTKExodusFileReader',
-  'VTKLegacyFileReader',
-  'VTKXMLFileReader',
-  'VTKPLYFileReader'
-]
-
-export default PolyDataIOIndex
diff --git a/dist/umd/index.html b/dist/umd/index.html
deleted file mode 100644
index e8886a1d4..000000000
--- a/dist/umd/index.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
-    <title>itk-wasm</title>
-    <script src="./itk-wasm.js"></script>
-  </head>
-  <body>
-    <div>
-      <label>Select image:</label>
-      <input name="inputFile" type="file">
-    </div>
-
-    <div>
-      <textarea name="fileInformation" rows="200" cols="80">File information...</textarea>
-    </div>
-
-    <script>
-      function outputFileInformation (event) {
-        var dataTransfer = event.dataTransfer
-        var files = event.target.files || dataTransfer.files
-        return itk.readImageFile(null, files[0])
-          .then(function ({ image, webWorker }) {
-            webWorker.terminate()
-            function replacer (key, value) {
-              if (!!value && value.byteLength !== undefined) {
-                return String(value.slice(0, 6)) + '...'
-              }
-              return value
-            }
-            var outputTextArea = document.querySelector('textarea')
-            outputTextArea.textContent = JSON.stringify(image, replacer, 4)
-          })
-      }
-
-      var fileInput = document.querySelector('input')
-      fileInput.addEventListener('change', outputFileInformation);
-    </script>
-  </body>
-</html>
diff --git a/docs/development/itk_js_to_itk_wasm_migration_guide.md b/docs/development/itk_js_to_itk_wasm_migration_guide.md
index cf0811917..b99958964 100644
--- a/docs/development/itk_js_to_itk_wasm_migration_guide.md
+++ b/docs/development/itk_js_to_itk_wasm_migration_guide.md
@@ -1,10 +1,10 @@
-# Migration Guide: From itk.js to itk-wasm
+# Migration Guide: From itk.js to ITK-Wasm
 
-*Note: itk-wasm is currently in the beta development stage. The interface is relatively stable while functionality is currently being fleshed out. Updates for the rest of the documentation for changes from itk.js to itk-wasm is in progress. Last updated August 5th, 2023.*
+*Note: ITK-Wasm is currently in the beta development stage. The interface is relatively stable while functionality is currently being fleshed out. Updates for the rest of the documentation for changes from itk.js to ITK-Wasm is in progress. Last updated December 14th, 2023.*
 
-**itk-wasm** is a major upgrade with a focus on universal, performant computing in WebAssembly. The itk.js to itk-wasm transition also brings improvements, including modern, elegant programming interfaces, accelerated performance, and execution beyond JavaScript thanks to [WASI](https://wasi.dev).
+**ITK-Wasm** is a major upgrade with a focus on universal, performant computing in WebAssembly. The itk.js to ITK-Wasm transition also brings improvements, including modern, elegant programming interfaces, accelerated performance, and execution beyond JavaScript thanks to [WASI](https://wasi.dev).
 
-Most itk.js client code will simply need to update its import statements to leverage itk-wasm. However, there are also other more advanced changes. A description of the changes, their motivation, and example migration code can be found below.
+Most itk.js client code will simply need to update its import statements to leverage ITK-Wasm. However, there are also other more advanced changes. A description of the changes, their motivation, and example migration code can be found below.
 
 ## Module import statements
 
@@ -37,57 +37,103 @@ import { IntTypes } from 'itk-wasm'
 
 ## TypeScript support
 
-Typescript support was added, but, of course, you can still just use JavaScript if you wish. In itk-wasm, adoption of modern JavaScript constructs was extended, e.g. classes.
+Typescript support was added, but, of course, you can still just use JavaScript if you wish. In ITK-Wasm, adoption of modern JavaScript constructs was extended, e.g. classes.
 
 ## Bundlers
 
-ECMAScript Module (ESM) support was improved.
+ECMAScript Module (ESM) support is now standard.
 
 There is now an improved approach for web workers for bundlers, CORS constraints.
 
+## itkConfig.js removed
+
+The `itkConfig.js` module in itk-js and initial versions of ITK-Wasm specified where to look for the io webassembly modules and an optional default base URL for pipeline modules.
+
+This build-time approach has been replaced by a run-time configuration approach, which is much easier to specify and works transparently in a nested dependency situation.
+
+There are now only two configuration settings.
+
+1. The location of the web worker module.
+2. The location of wasm module assets.
+
+### Specification of the web worker module location
+
+By default, the web worker module will be picked up by modern bundlers like Vite or WebPack without additional configuration, and the bundler will manage the location of and deployment of the bundle in a application build.
+
+ITK-Wasm packages also contain module bundle that embed the web workers.
+
+Finally, on an individual ITK-Wasm package scope or bundle scope via the `itk-wasm` package, the web worker can be vendored and its location at specified at runtime via `setPipelineWorkerUrl`.
+
+### Specification of the wasm asset location
+
+Previously, separate wasm asset locations were configured for io modules and general pipelines. Now, there is a single wasm asset configuration. It can be set on a per-package level or a common configuration for a bundle can be set.
+
+By default, the wasm asset location is configured to use the [JsDelivr](https://www.jsdelivr.com/) CDN for a package.
+
+On an individual ITK-Wasm package scope or bundle scope via the `itk-wasm` package, wasm assets can be vendored and their location specified at runtime via `setPipelinesBaseUrl`.
+
 ## IO modules are available in separate packages.
 
 IO modules are now installed in separate npm packages to limit the `itk-wasm` package size. You can install only the packages that you need.
 
-The version of these packages follow the `itk-wasm` package version and should be kept in sync. The io packages are:
+The io packages are:
 
-1. `itk-image-io`
-2. `itk-mesh-io`
+1. `@itk-wasm/image-io`
+2. `@itk-wasm/mesh-io`
 3. `@itk-wasm/dicom`
 
-An example that vendors these package's webassembly assets into an application for deployment can be found in the [Webpack Example](https://github.com/InsightSoftwareConsortium/itk-wasm/tree/main/examples/Webpack).
+An example that vendors these package's webassembly assets into an application for deployment can be found in the [Vite-based test applcation configuration](https://github.com/InsightSoftwareConsortium/itk-wasm/blob/main/packages/mesh-io/typescript/vite.config.js).
 
 ### DICOM image IO functions
 
 The following DICOM image IO functions have been migrated to the `@itk-wasm/dicom` package. Their interface changed in some cases.
 
 1. `readImageLocalDICOMFileSeries` -> `readImageDicomFileSeriesNode`
-1. `readImageDICOMFileSeries` -> `readImageDicomFileSeries`
-1. `readImageDICOMArrayBufferSeries` -> `readImageDicomFileSeries`
-1. `readDICOMTags` -> `readDicomTags`
-1. `readDICOMTagsArrayBuffer` -> `readDicomTags`
-1. `readDICOMTagsLocalFile` -> `readDicomTagsNode`
+2. `readImageDICOMFileSeries` -> `readImageDicomFileSeries`
+3. `readImageDICOMArrayBufferSeries` -> `readImageDicomFileSeries`
+4. `readDICOMTags` -> `readDicomTags`
+5. `readDICOMTagsArrayBuffer` -> `readDicomTags`
+6. `readDICOMTagsLocalFile` -> `readDicomTagsNode`
 
-## itkConfig.js content and usage
+### Migrated image-io and mesh-io functions
 
-The `itkConfig.js` specifies where to look for the io webassembly modules and an optional default base URL for pipeline modules.
+The following image and mesh IO functions have been migrated to the `@itk-wasm/image-io`
+and `@itk-wasm/mesh-io` package. Their interface changed in some cases.
 
-The default `itkConfig.js` is configured to use the [JsDelivr](https://www.jsdelivr.com/) CDN, but you may want to override this default.
+1. `readImageArrayBuffer` -> `readImageFile`
+2. `readImageBlob` -> `readImageFile`
+3. `readImageFileSeries` -> `readImageFileSeries`
+4. `readImageHTTP` -> `readImageHttp`
+5. `readImageLocalFile` -> `readImageNode`
+6. `readMeshArrayBuffer` -> `readMeshFile`
+7. `readMeshBlob` -> `readMeshFile`
+8. `readMeshLocalFile` -> `readMeshNode`
+9. `writeImageArrayBuffer` -> `writeImageFile`
+10. `writeImageLocalFile` -> `writeImageFileNode`
+11. `writeMeshArrayBuffer` -> `writeMeshFile`
+12. `writeMeshLocalFile` -> `writeMeshNode`
 
-In the [Webpack Example](https://github.com/InsightSoftwareConsortium/itk-wasm/tree/main/examples/Webpack) the io webassembly module assets are vendored into `/itk` directories, this module looks like:
+### MeshToPolyData
 
-```js
-const itkConfig = {
-  pipelineWorkerUrl: '/itk/web-workers/bundles/pipeline-worker.js',
-  imageIOUrl: '/itk/image-io',
-  meshIOUrl: '/itk/mesh-io',
-  pipelinesUrl: '/itk/pipelines',
-}
-
-export default itkConfig
-```
+The following mesh to polydata conversion functions have been migrated to the `@itk-wasm/mesh-to-poly-data` package.
+
+1. `meshToPolyData`
+2. `meshToPolyDataNode`
+3. `polyDataToMesh`
+4. `polyDataToMeshNode`
+
+### Removed high level IO functions
+
+The high level IO functions, that dealt with both images and meshes have been removed.
+
+These are:
 
-And it can be injected into an application bundle by setting defining `alias`'s to the configuration module for `../itkConfig.js` and `../../itkConfig.js`. For other override configuration options, see the [Webpack](https://github.com/InsightSoftwareConsortium/itk-wasm/tree/main/examples/Webpack) and Rollup (todo) examples.
+1. readArrayBuffer
+2. readBlob
+3. readFile
+4. readLocalFile
+5. writeArrayBuffer
+5. writeLocalFile
 
 ## CLI options
 
@@ -135,7 +181,7 @@ Support for the legacy GE image file formats, i.e. GE4, GE5, GEAdw, is no longer
 
 ## IOTypes
 
-The use of `IOTypes` in pipelines is deprecated and not expected to work in the future. These have been replaced by `InterfaceTypes`.
+The use of `IOTypes` in pipelines is deprecated has been removed. These have been replaced by `InterfaceTypes`.
 
 ## Argument order when writing image, mesh binaries
 
diff --git a/karma.conf.cjs b/karma.conf.cjs
deleted file mode 100644
index 7887def3b..000000000
--- a/karma.conf.cjs
+++ /dev/null
@@ -1,110 +0,0 @@
-/* eslint-disable global-require */
-/* eslint-disable react/require-extension */
-const os = require('os')
-const path = require('path')
-const webpack = require('webpack')
-const sourcePath = path.resolve(__dirname, './dist')
-
-if (!process.env.NODE_ENV) process.env.NODE_ENV = 'test'
-
-if (!process.env.CHROME_BIN) {
-  process.env.CHROME_BIN = require('puppeteer').executablePath()
-}
-
-const testFiles = ['./test/browser/tests.js',]
-if (process.env.NO_VTK !== '1') {
-  testFiles.push('./test/browser/testsVTK.js')
-}
-
-const testConfig = path.resolve(__dirname, 'test', 'browser', 'config', 'itkConfigBrowserTest.js')
-
-// https://github.com/ryanclark/karma-webpack/issues/498]
-const output = {
-  path: path.join(os.tmpdir(), '_karma_webpack_') + Math.floor(Math.random() * 1000000)
-}
-
-module.exports = function init (config) {
-  config.set({
-    plugins: [
-      require('karma-webpack'),
-      require('karma-tap'),
-      require('karma-chrome-launcher'),
-      require('karma-tap-pretty-reporter')
-    ],
-
-    basePath: '',
-    frameworks: ['tap', 'webpack'],
-    files: [
-      { pattern: './dist/image-io/**', watched: true, served: true, included: false },
-      { pattern: './dist/mesh-io/**', watched: true, served: true, included: false },
-      { pattern: './dist/core/web-workers/**', watched: true, served: true, included: false },
-      { pattern: './dist/pipelines/**', watched: true, served: true, included: false },
-      { pattern: './build-emscripten/ExternalData/test/**', watched: true, served: true, included: false },
-      { pattern: `${output.path}/**/*`, watched: false, included: false, },
-    ].concat(testFiles),
-
-    preprocessors: {
-      './test/browser/**/*.js': ['webpack']
-    },
-
-    webpack: {
-      mode: 'development',
-      module: {
-        rules: [].concat()
-      },
-      output,
-      resolve: {
-        modules: [
-          path.resolve(__dirname, 'node_modules'),
-          sourcePath
-        ],
-        fallback: {
-          assert: false,
-          module: false,
-          url: false,
-          path: require.resolve('path-browserify'),
-          fs: false,
-        },
-        alias: {
-          '../itkConfig.js': testConfig,
-          '../../itkConfig.js': testConfig,
-          stream: 'stream-browserify',
-        }
-      },
-      plugins: [
-        new webpack.DefinePlugin({
-          __BASE_PATH__: "'/base'",
-        }),
-        new webpack.ProvidePlugin({ process: ['process/browser'] }),
-      ],
-    },
-
-    webpackMiddleware: {
-      noInfo: true
-    },
-
-    reporters: [
-      'tap-pretty'
-    ],
-
-    client: {
-      useIframe: true
-    },
-
-    customLaunchers: {
-      ChromeHeadlessNoSandbox: {
-        base: 'ChromeHeadless',
-        flags: ['--no-sandbox']
-      }
-    },
-    // browserNoActivityTimeout: 600000,
-    // browserDisconnectTimeout: 600000,
-
-    port: 9876,
-    colors: true,
-    logLevel: config.LOG_INFO,
-    autoWatch: true,
-    browsers: ['Chrome'],
-    singleRun: true
-  })
-}
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/index-common.ts b/packages/core/typescript/itk-wasm/src/deprecated/index-common.ts
new file mode 100644
index 000000000..76e45b657
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/index-common.ts
@@ -0,0 +1,1 @@
+// Common deprecated modules across browser and node.js
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/index-node.ts b/packages/core/typescript/itk-wasm/src/deprecated/index-node.ts
new file mode 100644
index 000000000..e554947ff
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/index-node.ts
@@ -0,0 +1,20 @@
+import readDICOMTagsLocalFile from "./read-dicom-tags-local-file.js"
+export { readDICOMTagsLocalFile }
+
+import readImageLocalDICOMFileSeries from "./read-image-local-dicom-file-series.js"
+export { readImageLocalDICOMFileSeries }
+
+import meshToPolyDataNode from "./mesh-to-poly-data-node.js"
+export { meshToPolyDataNode }
+
+import polyDataToMeshNode from "./poly-data-to-mesh-node.js"
+export { polyDataToMeshNode }
+
+import readMeshLocalFile from "./read-mesh-local-file.js"
+export { readMeshLocalFile }
+
+import writeImageLocalFile from "./write-image-local-file.js"
+export { writeImageLocalFile }
+
+import readImageLocalFile from "./read-image-local-file.js"
+export { readImageLocalFile }
\ No newline at end of file
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/index.ts b/packages/core/typescript/itk-wasm/src/deprecated/index.ts
new file mode 100644
index 000000000..d695af73a
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/index.ts
@@ -0,0 +1,41 @@
+import ReadDICOMTagsResult from './read-dicom-tags-result.js'
+export type { ReadDICOMTagsResult }
+
+import readDICOMTags from './read-dicom-tags.js'
+export { readDICOMTags }
+
+import readDICOMTagsArrayBuffer from './read-dicom-tags-array-buffer.js'
+export { readDICOMTagsArrayBuffer }
+
+import readImageDICOMFileSeries from './read-image-dicom-file-series.js'
+export { readImageDICOMFileSeries }
+
+import ReadImageDICOMFileSeriesResult from './read-image-dicom-file-series-result.js'
+export type { ReadImageDICOMFileSeriesResult }
+
+import readImageDICOMArrayBufferSeries from './read-image-dicom-array-buffer-series.js'
+export { readImageDICOMArrayBufferSeries }
+
+import meshToPolyData from './mesh-to-poly-data.js'
+export { meshToPolyData }
+
+import polyDataToMesh from './poly-data-to-mesh.js'
+export { polyDataToMesh }
+
+import readImageArrayBuffer from './read-image-array-buffer.js'
+export { readImageArrayBuffer }
+
+import readImageBlob from './read-image-blob.js'
+export { readImageBlob }
+
+import readImageFile from './read-image-file.js'
+export { readImageFile }
+
+import readImageFileSeries from './read-image-file-series.js'
+export { readImageFileSeries }
+
+import readMeshArrayBuffer from './read-mesh-array-buffer.js'
+export { readMeshArrayBuffer }
+
+import readMeshFile from './read-mesh-file.js'
+export { readMeshFile }
\ No newline at end of file
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/mesh-to-poly-data-node.ts b/packages/core/typescript/itk-wasm/src/deprecated/mesh-to-poly-data-node.ts
new file mode 100644
index 000000000..0069d58db
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/mesh-to-poly-data-node.ts
@@ -0,0 +1,14 @@
+// @ts-nocheck
+
+import Mesh from '../interface-types/mesh.js'
+import PolyData from '../interface-types/poly-data.js'
+
+
+/**
+ * @deprecated Use meshToPolyDataNode from @itk-wasm/mesh-to-poly-data instead
+ */
+async function meshToPolyDataNode (mesh: Mesh): Promise<PolyData> {
+  throw new Error('This function has been migrated to the @itk-wasm/mesh-to-poly-data package.')
+}
+
+export default meshToPolyDataNode
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/mesh-to-poly-data.ts b/packages/core/typescript/itk-wasm/src/deprecated/mesh-to-poly-data.ts
new file mode 100644
index 000000000..ec68933b5
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/mesh-to-poly-data.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+
+import Mesh from '../interface-types/mesh.js'
+import PolyData from '../interface-types/poly-data.js'
+
+/**
+ * @deprecated Use meshToPolyData from @itk-wasm/mesh-to-poly-data instead
+ */
+async function meshToPolyData (webWorker: Worker | null, mesh: Mesh): Promise<{ polyData: PolyData, webWorker: Worker }> {
+  throw new Error('This function has been migrated to the @itk-wasm/mesh-to-poly-data package.')
+}
+
+export default meshToPolyData
diff --git a/src/io/polyDataToMeshNode.ts b/packages/core/typescript/itk-wasm/src/deprecated/poly-data-to-mesh-node.ts
similarity index 52%
rename from src/io/polyDataToMeshNode.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/poly-data-to-mesh-node.ts
index a8d55dc95..24bbfb7d9 100644
--- a/src/io/polyDataToMeshNode.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/poly-data-to-mesh-node.ts
@@ -1,14 +1,12 @@
-import path from 'path'
+// @ts-nocheck
 
-import Mesh from '../core/interface-types/mesh.js'
-import PolyData from '../core/interface-types/poly-data.js'
-import findLocalMeshIOPath from './internal/findLocalMeshIOPath.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import loadEmscriptenModule from './../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from '../pipeline/internal/runPipelineEmscripten.js'
-import PipelineEmscriptenModule from '../pipeline/PipelineEmscriptenModule.js'
+import Mesh from '../interface-types/mesh.js'
+import PolyData from '../interface-types/poly-data.js'
 
+
+/**
+ * @deprecated Use polyDataToMeshNode from @itk-wasm/mesh-to-poly-data instead
+ */
 async function polyDataToMeshNode (polyData: PolyData): Promise<Mesh> {
   const meshIOsPath = findLocalMeshIOPath()
 
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/poly-data-to-mesh.ts b/packages/core/typescript/itk-wasm/src/deprecated/poly-data-to-mesh.ts
new file mode 100644
index 000000000..d0be594dd
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/poly-data-to-mesh.ts
@@ -0,0 +1,14 @@
+// @ts-nocheck
+
+import Mesh from '../interface-types/mesh.js'
+import PolyData from '../interface-types/poly-data.js'
+
+
+/**
+ * @deprecated Use polyDataToMesh from @itk-wasm/mesh-to-poly-data instead
+ */
+async function polyDataToMesh (webWorker: Worker | null, polyData: PolyData): Promise<{ mesh: Mesh, webWorker: Worker }> {
+  throw new Error('This function has been migrated to the @itk-wasm/mesh-to-poly-data package.')
+}
+
+export default polyDataToMesh
diff --git a/src/io/deprecated/readDICOMTagsArrayBuffer.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-array-buffer.ts
similarity index 83%
rename from src/io/deprecated/readDICOMTagsArrayBuffer.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-array-buffer.ts
index f5ab2cdb2..4bfe75367 100644
--- a/src/io/deprecated/readDICOMTagsArrayBuffer.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-array-buffer.ts
@@ -1,4 +1,6 @@
-import ReadDICOMTagsResult from './ReadDICOMTagsResult.js'
+// @ts-nocheck
+
+import ReadDICOMTagsResult from './read-dicom-tags-result.js'
 
 /**
  *
diff --git a/src/io/deprecated/readDICOMTagsLocalFile.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-local-file.ts
similarity index 95%
rename from src/io/deprecated/readDICOMTagsLocalFile.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-local-file.ts
index 905da3056..42042d967 100644
--- a/src/io/deprecated/readDICOMTagsLocalFile.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-local-file.ts
@@ -1,3 +1,5 @@
+// @ts-nocheck
+
 /**
  *
  * @deprecated Use readDicomTagsNode from @itk-wasm/dicom instead
diff --git a/src/io/deprecated/ReadDICOMTagsResult.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-result.ts
similarity index 100%
rename from src/io/deprecated/ReadDICOMTagsResult.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags-result.ts
diff --git a/src/io/deprecated/readDICOMTags.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags.ts
similarity index 80%
rename from src/io/deprecated/readDICOMTags.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags.ts
index 815ce161b..1e531b6b8 100644
--- a/src/io/deprecated/readDICOMTags.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-dicom-tags.ts
@@ -1,4 +1,6 @@
-import ReadDICOMTagsResult from './ReadDICOMTagsResult.js'
+// @ts-nocheck
+
+import ReadDICOMTagsResult from './read-dicom-tags-result.js'
 
 /**
  * @deprecated Use readDicomTags from @itk-wasm/dicom instead
diff --git a/src/io/ReadImageArrayBufferOptions.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-array-buffer-options.ts
similarity index 69%
rename from src/io/ReadImageArrayBufferOptions.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-array-buffer-options.ts
index 5807e3fe2..ef1eef4f7 100644
--- a/src/io/ReadImageArrayBufferOptions.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-array-buffer-options.ts
@@ -1,4 +1,4 @@
-import CastImageOptions from '../core/CastImageOptions.js'
+import CastImageOptions from '../cast-image-options.js'
 
 interface ReadImageArrayBufferOptions extends CastImageOptions {
   mimeType?: string
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-image-array-buffer.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-array-buffer.ts
new file mode 100644
index 000000000..ae4d9037b
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-array-buffer.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+
+import ReadImageResult from "./read-image-result.js"
+import ReadImageArrayBufferOptions from "./read-image-array-buffer-options.js"
+
+/**
+ * @deprecated Use readImageArrayBuffer from @itk-wasm/image-io instead
+ */
+async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, options?: ReadImageArrayBufferOptions | string): Promise<ReadImageResult> {
+  throw new Error('readImageArrayBuffer is deprecated. Use readImageFile from @itk-wasm/image-io instead.')
+}
+
+export default readImageArrayBuffer
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-image-blob.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-blob.ts
new file mode 100644
index 000000000..f4fe99ad7
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-blob.ts
@@ -0,0 +1,13 @@
+// @ts-nocheck
+
+import ReadImageResult from "./read-image-result.js"
+import ReadImageArrayBufferOptions from "./read-image-array-buffer-options.js"
+
+/**
+ * @deprecated Use readImageBlob from @itk-wasm/image-io instead
+ */
+async function readImageBlob (webWorker: Worker | null, blob: Blob, fileName: string, options?: ReadImageArrayBufferOptions | string): Promise<ReadImageResult> {
+  throw new Error('readImageBlob is deprecated. Use readImageFile from @itk-wasm/image-io instead.')
+}
+
+export default readImageBlob
diff --git a/src/io/deprecated/ReadImageDICOMArrayBufferSeriesOptions.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-array-buffer-series-options.ts
similarity index 81%
rename from src/io/deprecated/ReadImageDICOMArrayBufferSeriesOptions.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-array-buffer-series-options.ts
index 2e5953936..3f71009ba 100644
--- a/src/io/deprecated/ReadImageDICOMArrayBufferSeriesOptions.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-array-buffer-series-options.ts
@@ -1,4 +1,4 @@
-import CastImageOptions from '../../core/CastImageOptions.js'
+import CastImageOptions from '../cast-image-options.js'
 
 /**
  * @deprecated Use readImageDicomFileSeries from @itk-wasm/dicom instead
diff --git a/src/io/deprecated/readImageDICOMArrayBufferSeries.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-array-buffer-series.ts
similarity index 72%
rename from src/io/deprecated/readImageDICOMArrayBufferSeries.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-array-buffer-series.ts
index 3c32cbd3e..64aae00b0 100644
--- a/src/io/deprecated/readImageDICOMArrayBufferSeries.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-array-buffer-series.ts
@@ -1,5 +1,7 @@
-import ReadImageFileSeriesResult from '../ReadImageFileSeriesResult.js'
-import ReadImageDICOMArrayBufferSeriesOptions from './ReadImageDICOMArrayBufferSeriesOptions.js'
+// @ts-nocheck
+
+import ReadImageFileSeriesResult from '../read-image-file-series-result.js'
+import ReadImageDICOMArrayBufferSeriesOptions from './read-image-dicom-file-series-options.js'
 
 /**
  *
diff --git a/src/io/deprecated/ReadImageDICOMFileSeriesOptions.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series-options.ts
similarity index 78%
rename from src/io/deprecated/ReadImageDICOMFileSeriesOptions.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series-options.ts
index f4bb3ae93..3de6fc583 100644
--- a/src/io/deprecated/ReadImageDICOMFileSeriesOptions.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series-options.ts
@@ -1,4 +1,4 @@
-import CastImageOptions from '../../core/CastImageOptions.js'
+import CastImageOptions from '../cast-image-options.js'
 
 /**
  * @deprecated Use readImageDicomFileSeries from @itk-wasm/dicom instead
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series-result.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series-result.ts
new file mode 100644
index 000000000..a195fc9bf
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series-result.ts
@@ -0,0 +1,16 @@
+import Image from '../interface-types/image.js'
+import WorkerPool from '../worker-pool.js'
+
+interface ReadImageDicomFileSeriesResult {
+  /** WebWorkerPool used for computation */
+  webWorkerPool: WorkerPool | null
+
+  /** Output image volume */
+  outputImage: Image
+
+  /** Output sorted filenames */
+  sortedFilenames: Object
+
+}
+
+export default ReadImageDicomFileSeriesResult
diff --git a/src/io/deprecated/readImageDICOMFileSeries.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series.ts
similarity index 69%
rename from src/io/deprecated/readImageDICOMFileSeries.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series.ts
index bfbbea978..0baa6e057 100644
--- a/src/io/deprecated/readImageDICOMFileSeries.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-dicom-file-series.ts
@@ -1,5 +1,7 @@
-import ReadImageFileSeriesResult from '../ReadImageFileSeriesResult.js'
-import ReadImageDICOMFileSeriesOptions from './ReadImageDICOMFileSeriesOptions.js'
+// @ts-nocheck
+
+import ReadImageFileSeriesResult from './read-image-dicom-file-series-result.js'
+import ReadImageDICOMFileSeriesOptions from './read-image-dicom-file-series-options.js'
 
 /**
  * @deprecated Use readImageDicomFileSeries from @itk-wasm/dicom instead
diff --git a/src/io/ReadImageFileSeriesOptions.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series-options.ts
similarity index 74%
rename from src/io/ReadImageFileSeriesOptions.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series-options.ts
index cf5c283b0..2d354b972 100644
--- a/src/io/ReadImageFileSeriesOptions.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series-options.ts
@@ -1,4 +1,4 @@
-import CastImageOptions from '../core/CastImageOptions.js'
+import CastImageOptions from '../cast-image-options.js'
 
 interface ReadImageFileSeriesOptions extends CastImageOptions {
   zSpacing?: number
diff --git a/src/io/ReadImageFileSeriesResult.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series-result.ts
similarity index 55%
rename from src/io/ReadImageFileSeriesResult.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series-result.ts
index cdb186e51..ceee47b30 100644
--- a/src/io/ReadImageFileSeriesResult.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series-result.ts
@@ -1,5 +1,5 @@
-import Image from '../core/interface-types/image.js'
-import WorkerPool from '../core/WorkerPool.js'
+import Image from '../interface-types/image.js'
+import WorkerPool from '../worker-pool.js'
 
 interface ReadImageFileSeriesResult {
   image: Image
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series.ts
new file mode 100644
index 000000000..6345d6714
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file-series.ts
@@ -0,0 +1,18 @@
+// @ts-nocheck
+
+import ReadImageFileSeriesResult from './read-image-file-series-result.js'
+import ReadImageFileSeriesOptions from './read-image-file-series-options.js'
+
+/**
+ * @deprecated Use readImageFileSeries from @itk-wasm/image-io instead
+ */
+async function readImageFileSeries (
+  fileList: File[] | FileList,
+  options?: ReadImageFileSeriesOptions | number,
+  zOriginBackwardsCompatibility?: number,
+  sortedSeriesBackwardsCompatibility?: boolean
+): Promise<ReadImageFileSeriesResult> {
+  throw new Error('readImageFileSeries is deprecated. Use readImageFileSeries from @itk-wasm/image-io instead.')
+}
+
+export default readImageFileSeries
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-image-file.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file.ts
new file mode 100644
index 000000000..b82592aea
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-file.ts
@@ -0,0 +1,14 @@
+// @ts-nocheck
+
+import ReadImageResult from "./read-image-result.js"
+
+import CastImageOptions from "../cast-image-options.js"
+
+/**
+ * @deprecated Use readImageFile from @itk-wasm/image-io instead
+ */
+async function readImageFile (webWorker: Worker | null, file: File, options?: CastImageOptions): Promise<ReadImageResult> {
+  throw new Error('readImageFile is deprecated. Use readImageFile from @itk-wasm/image-io instead.')
+}
+
+export default readImageFile
diff --git a/src/io/deprecated/readImageLocalDICOMFileSeries.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-local-dicom-file-series.ts
similarity index 72%
rename from src/io/deprecated/readImageLocalDICOMFileSeries.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-local-dicom-file-series.ts
index 1631911a9..bc86eb8a0 100644
--- a/src/io/deprecated/readImageLocalDICOMFileSeries.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-local-dicom-file-series.ts
@@ -1,5 +1,7 @@
-import ReadImageDICOMFileSeriesOptions from './ReadImageDICOMFileSeriesOptions.js'
-import Image from '../../core/interface-types/image.js'
+// @ts-nocheck
+
+import ReadImageDICOMFileSeriesOptions from './read-image-dicom-file-series-options.js'
+import Image from '../interface-types/image.js'
 
 /**
  * @deprecated Use readImageDicomFileSeriesNode from @itk-wasm/dicom instead
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-image-local-file.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-local-file.ts
new file mode 100644
index 000000000..07ee1b958
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-local-file.ts
@@ -0,0 +1,14 @@
+// @ts-nocheck
+
+import Image from '../interface-types/image.js'
+
+import CastImageOptions from '../cast-image-options.js'
+
+/**
+ * @deprecated Use readImageFileNode from @itk-wasm/image-io instead
+ */
+async function readImageLocalFile (filePath: string, options?: CastImageOptions): Promise<Image> {
+  throw new Error('readImageLocalFile is deprecated. Use readImageFileNode from @itk-wasm/image-io instead.')
+}
+
+export default readImageLocalFile
diff --git a/src/io/ReadImageResult.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-image-result.ts
similarity index 64%
rename from src/io/ReadImageResult.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-image-result.ts
index e3f909fcf..df771ff99 100644
--- a/src/io/ReadImageResult.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-image-result.ts
@@ -1,4 +1,4 @@
-import Image from '../core/interface-types/image.js'
+import Image from '../interface-types/image.js'
 
 interface ReadImageResult {
   image: Image
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-array-buffer.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-array-buffer.ts
new file mode 100644
index 000000000..85a6890dd
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-array-buffer.ts
@@ -0,0 +1,12 @@
+// @ts-nocheck
+
+import ReadMeshResult from './read-mesh-result.js'
+
+/**
+ * @deprecated Use readMeshArrayBuffer from @itk-wasm/image-io instead
+ */
+async function readMeshArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, mimeType: string): Promise<ReadMeshResult> {
+  throw new Error('readMeshArrayBuffer is deprecated. Use readMeshFile from @itk-wasm/mesh-io instead.')
+}
+
+export default readMeshArrayBuffer
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-blob.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-blob.ts
new file mode 100644
index 000000000..ea5622d02
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-blob.ts
@@ -0,0 +1,12 @@
+// @ts-nocheck
+
+import ReadMeshResult from './read-mesh-result.js'
+
+/**
+ * @deprecated Use readMeshBlob from @itk-wasm/mesh-io instead
+ */
+async function readMeshBlob (webWorker: Worker | null, blob: Blob, fileName: string, mimeType: string): Promise<ReadMeshResult> {
+  throw new Error('readMeshBlob is deprecated. Use readMeshFile from @itk-wasm/mesh-io instead.')
+}
+
+export default readMeshBlob
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-file.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-file.ts
new file mode 100644
index 000000000..a1659392d
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-file.ts
@@ -0,0 +1,12 @@
+// @ts-nocheck
+
+import ReadMeshResult from './read-mesh-result.js'
+
+/**
+ * @deprecated Use readMeshFile from @itk-wasm/mesh-io instead
+ */
+async function readMeshFile (webWorker: Worker | null, file: File): Promise<ReadMeshResult> {
+  throw new Error('readMeshFile is deprecated. Use readMeshFile from @itk-wasm/mesh-io instead.')
+}
+
+export default readMeshFile
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-local-file.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-local-file.ts
new file mode 100644
index 000000000..d3601b961
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-local-file.ts
@@ -0,0 +1,12 @@
+// @ts-nocheck
+
+import Mesh from '../interface-types/mesh.js'
+
+/**
+ * @deprecated Use readMeshFileNode from @itk-wasm/mesh-io instead
+ */
+async function readMeshLocalFile (filePath: string): Promise<Mesh> {
+  throw new Error('readMeshLocalFile is deprecated. Use readMeshFileNode from @itk-wasm/mesh-io instead.')
+}
+
+export default readMeshLocalFile
diff --git a/src/io/ReadMeshResult.ts b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-result.ts
similarity index 64%
rename from src/io/ReadMeshResult.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/read-mesh-result.ts
index ed6c96984..3301d2f9f 100644
--- a/src/io/ReadMeshResult.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/read-mesh-result.ts
@@ -1,4 +1,4 @@
-import Mesh from '../core/interface-types/mesh.js'
+import Mesh from '../interface-types/mesh.js'
 
 interface ReadMeshResult {
   mesh: Mesh
diff --git a/src/io/WriteArrayBufferResult.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-array-buffer-result.ts
similarity index 100%
rename from src/io/WriteArrayBufferResult.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/write-array-buffer-result.ts
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/write-image-array-buffer.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-image-array-buffer.ts
new file mode 100644
index 000000000..638e17032
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/write-image-array-buffer.ts
@@ -0,0 +1,16 @@
+// @ts-nocheck
+
+import Image from '../interface-types/image.js'
+
+import WriteImageOptions from './write-image-options.js'
+import WriteArrayBufferResult from './write-array-buffer-result.js'
+
+/**
+ * @deprecated Use writeImageFile from @itk-wasm/image-io instead
+ */
+async function writeImageArrayBuffer (webWorker: Worker | null, image: Image, fileName: string, options?: WriteImageOptions | string, useCompressionBackwardsCompatibility?: boolean
+): Promise<WriteArrayBufferResult> {
+  throw new Error('writeImageArrayBuffer is deprecated. Use writeImageFile from @itk-wasm/image-io instead.')
+}
+
+export default writeImageArrayBuffer
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/write-image-local-file.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-image-local-file.ts
new file mode 100644
index 000000000..9362cea26
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/write-image-local-file.ts
@@ -0,0 +1,15 @@
+// @ts-nocheck
+
+import WriteImageOptions from './write-image-options.js'
+
+import Image from '../interface-types/image.js'
+
+/**
+ * @deprecated Use writeImageFileNode from @itk-wasm/image-io instead
+ */
+async function writeImageLocalFile (image: Image, filePath: string, options?: WriteImageOptions | boolean
+): Promise<null> {
+  throw new Error('writeImageLocalFile is deprecated. Use writeImageFileNode from @itk-wasm/image-io instead.')
+}
+
+export default writeImageLocalFile
diff --git a/src/io/WriteImageOptions.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-image-options.ts
similarity index 70%
rename from src/io/WriteImageOptions.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/write-image-options.ts
index e234f72a1..e72fe7cf9 100644
--- a/src/io/WriteImageOptions.ts
+++ b/packages/core/typescript/itk-wasm/src/deprecated/write-image-options.ts
@@ -1,4 +1,4 @@
-import CastImageOptions from '../core/CastImageOptions.js'
+import CastImageOptions from '../cast-image-options.js'
 
 interface WriteImageOptions extends CastImageOptions {
   useCompression?: boolean
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-array-buffer.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-array-buffer.ts
new file mode 100644
index 000000000..166cdb7bb
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-array-buffer.ts
@@ -0,0 +1,15 @@
+// @ts-nocheck
+
+import Mesh from '../interface-types/mesh.js'
+
+import WriteArrayBufferResult from './write-array-buffer-result.js'
+import WriteMeshOptions from './write-mesh-options.js'
+
+/**
+ * @deprecated Use writeMeshFile from @itk-wasm/mesh-io instead
+ */
+async function writeMeshArrayBuffer (webWorker: Worker | null, mesh: Mesh, fileName: string, mimeType: string, options: WriteMeshOptions): Promise<WriteArrayBufferResult> {
+  throw new Error('writeMeshArrayBuffer is deprecated. Use writeMeshFile from @itk-wasm/mesh-io instead.')
+}
+
+export default writeMeshArrayBuffer
diff --git a/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-local-file.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-local-file.ts
new file mode 100644
index 000000000..d8efdc490
--- /dev/null
+++ b/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-local-file.ts
@@ -0,0 +1,14 @@
+// @ts-nocheck
+
+import WriteMeshOptions from './write-mesh-options.js'
+
+import Mesh from '../interface-types/mesh.js'
+
+/**
+ * @deprecated Use writeMeshFileNode from @itk-wasm/mesh-io instead
+ */
+async function writeMeshLocalFile (mesh: Mesh, filePath: string, options: WriteMeshOptions): Promise<null> {
+  throw new Error('writeMeshLocalFile is deprecated. Use writeMeshFileNode from @itk-wasm/mesh-io instead.')
+}
+
+export default writeMeshLocalFile
diff --git a/src/io/WriteMeshOptions.ts b/packages/core/typescript/itk-wasm/src/deprecated/write-mesh-options.ts
similarity index 100%
rename from src/io/WriteMeshOptions.ts
rename to packages/core/typescript/itk-wasm/src/deprecated/write-mesh-options.ts
diff --git a/packages/core/typescript/itk-wasm/src/index-common.ts b/packages/core/typescript/itk-wasm/src/index-common.ts
index 42dd378f2..55911fc8e 100644
--- a/packages/core/typescript/itk-wasm/src/index-common.ts
+++ b/packages/core/typescript/itk-wasm/src/index-common.ts
@@ -20,3 +20,4 @@ export type { default as WorkerPoolProgressCallback } from './worker-pool-progre
 
 export * from './interface-types/index-common.js'
 export * from './pipeline/index-common.js'
+// export * from './deprecated/index-common.js'
diff --git a/packages/core/typescript/itk-wasm/src/index-node.ts b/packages/core/typescript/itk-wasm/src/index-node.ts
index 75bb5404e..f5e387c58 100644
--- a/packages/core/typescript/itk-wasm/src/index-node.ts
+++ b/packages/core/typescript/itk-wasm/src/index-node.ts
@@ -3,3 +3,5 @@
 export * from './index-common.js'
 
 export * from './pipeline/index-node.js'
+
+export * from './deprecated/index-node.js'
diff --git a/packages/core/typescript/itk-wasm/src/index.ts b/packages/core/typescript/itk-wasm/src/index.ts
index bd3e1d3f4..ca0ab1a75 100644
--- a/packages/core/typescript/itk-wasm/src/index.ts
+++ b/packages/core/typescript/itk-wasm/src/index.ts
@@ -3,3 +3,5 @@
 export * from './index-common.js'
 
 export * from './pipeline/index.js'
+
+export * from './deprecated/index.js'
diff --git a/packages/image-io/typescript/package.json b/packages/image-io/typescript/package.json
index fe6cd7d20..b00f446bd 100644
--- a/packages/image-io/typescript/package.json
+++ b/packages/image-io/typescript/package.json
@@ -45,6 +45,7 @@
   "author": "",
   "license": "Apache-2.0",
   "dependencies": {
+    "axios": "^1.6.2",
     "itk-wasm": "workspace:^",
     "mime-types": "^2.1.35"
   },
diff --git a/packages/image-io/typescript/src/index.ts b/packages/image-io/typescript/src/index.ts
index c560afd7f..051be187e 100644
--- a/packages/image-io/typescript/src/index.ts
+++ b/packages/image-io/typescript/src/index.ts
@@ -1,6 +1,9 @@
 export * from './pipelines-base-url.js'
 export * from './pipeline-worker-url.js'
 
+import readImageHttp from './read-image-http.js'
+export { readImageHttp }
+
 import ReadImageOptions from './read-image-options.js'
 export type { ReadImageOptions }
 
diff --git a/src/io/readImageHTTP.ts b/packages/image-io/typescript/src/read-image-http.ts
similarity index 74%
rename from src/io/readImageHTTP.ts
rename to packages/image-io/typescript/src/read-image-http.ts
index 9e11f70b9..345630997 100644
--- a/src/io/readImageHTTP.ts
+++ b/packages/image-io/typescript/src/read-image-http.ts
@@ -1,9 +1,6 @@
 import axios from 'axios'
 
-import bufferToTypedArray from '../core/bufferToTypedArray.js'
-import Image from '../core/interface-types/image.js'
-import FloatTypes from '../core/interface-types/float-types.js'
-import type TypedArray from '../core/TypedArray.js'
+import { bufferToTypedArray, Image, FloatTypes, TypedArray } from 'itk-wasm'
 
 async function readImageHTTP (url: string): Promise<Image> {
   const imageResponse = await axios.get(`${url}/index.json`, { responseType: 'json' })
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 54bf9211b..c30e343d2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -264,6 +264,9 @@ importers:
 
   packages/image-io/typescript:
     dependencies:
+      axios:
+        specifier: ^1.6.2
+        version: 1.6.2(debug@4.3.4)
       itk-wasm:
         specifier: workspace:^
         version: link:../../core/typescript/itk-wasm
diff --git a/src/browser/index.ts b/src/browser/index.ts
deleted file mode 100644
index 82ebdae44..000000000
--- a/src/browser/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-// itk-wasm Browser API interfaces, data structures, and functions
-
-export * from '../core/index.js'
-
-export * from '../core/pipeline-worker-url.js'
-export * from '../core/pipelines-base-url.js'
-
-export { default as ReadImageResult } from '../io/ReadImageResult.js'
-export { default as ReadMeshResult } from '../io/ReadMeshResult.js'
-
-export { default as ReadDICOMTagsResult } from '../io/deprecated/ReadDICOMTagsResult.js'
-
-export { default as WriteArrayBufferResult } from '../io/WriteArrayBufferResult.js'
-export { default as WriteMeshOptions } from '../io/WriteMeshOptions.js'
-
-export * from '../io/browser/index.js'
-
-export { default as PipelineInput } from '../pipeline/PipelineInput.js'
-export { default as PipelineOutput } from '../pipeline/PipelineOutput.js'
-export { default as RunPipelineResult } from '../pipeline/RunPipelineResult.js'
-export { default as RunPipelineOptions } from '../pipeline/RunPipelineOptions.js'
-
-export * from '../pipeline/browser/index.js'
diff --git a/src/build-emscripten.js b/src/build-emscripten.js
deleted file mode 100644
index 119e8e731..000000000
--- a/src/build-emscripten.js
+++ /dev/null
@@ -1,237 +0,0 @@
-#!/usr/bin/env node
-
-import fs from 'fs-extra'
-import path from 'path'
-import { spawnSync } from 'child_process'
-import glob from 'glob'
-import asyncMod from 'async'
-import promiseSpawn from '@npmcli/promise-spawn'
-
-import { Command } from 'commander/esm.mjs'
-
-const program = new Command()
-
-program
-  .option('-b, --no-build-io', 'Do not compile io modules')
-  .option('-s, --no-copy-build-artifacts', 'Do not copy build artifacts')
-  .option('-e, --no-build-test-pipelines', 'Do not build the emscripten test pipelines')
-  .option('-d, --debug', 'Create a debug build of the Emscripten modules')
-  .parse(process.argv)
-
-const options = program.opts()
-
-// Make the directory to hold build artifacts
-const buildDir = 'build-emscripten'
-try {
-  fs.mkdirSync('build')
-} catch (err) {
-  if (err.code !== 'EEXIST') throw err
-}
-
-if (options.buildIo) {
-  // Make the "build" directory to hold build artifacts
-  try {
-    fs.mkdirSync(buildDir)
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-
-  const dockerVersion = spawnSync('docker', ['--version'], {
-    env: process.env,
-    stdio: ['ignore', 'ignore', 'ignore']
-  })
-  if (dockerVersion.status !== 0) {
-    console.error("Could not run the 'docker' command.")
-    console.error('This package requires Docker to build.')
-    console.error('')
-    console.error('Please find installation instructions at:')
-    console.error('')
-    console.error('  https://docs.docker.com/install/')
-    console.error('')
-    process.exit(dockerVersion.status)
-  }
-
-  // Ensure we have the 'dockcross' Docker build environment driver script
-  let dockcross = `${buildDir}/dockcross`
-  if (options.debug) {
-    dockcross = `${buildDir}/dockcross-debug`
-  }
-  try {
-    fs.statSync(dockcross)
-  } catch (err) {
-    if (err.code === 'ENOENT') {
-      const output = fs.openSync(dockcross, 'w')
-      let buildImage = 'itkwasm/emscripten:latest'
-      if (options.debug) {
-        buildImage = 'itkwasm/emscripten:latest-debug'
-      }
-      const dockerCall = spawnSync('docker', ['run', '--rm', buildImage], {
-        env: process.env,
-        stdio: ['ignore', output, null]
-      })
-      if (dockerCall.status !== 0) {
-        process.exit(dockerCall.status)
-      }
-      fs.closeSync(output)
-      fs.chmodSync(dockcross, '755')
-    } else {
-      throw err
-    }
-  }
-
-  // Perform initial CMake configuration if required
-  try {
-    fs.statSync(path.join(buildDir, 'build.ninja'))
-  } catch (err) {
-    if (err.code === 'ENOENT') {
-      let buildType = '-DCMAKE_BUILD_TYPE:STRING=Release'
-      if (options.debug) {
-        buildType = '-DCMAKE_BUILD_TYPE:STRING=Debug'
-      }
-      const cmakeCall = spawnSync('bash', [dockcross, 'bash', '-c', `cmake ${buildType} -B${buildDir} -H. -GNinja -DITK_DIR=/ITK-build -DITK_WASM_NO_INTERFACE_LINK=1 -DBUILD_ITK_WASM_IO_MODULES=ON`], {
-        env: process.env,
-        stdio: 'inherit'
-      })
-      if (cmakeCall.status !== 0) {
-        process.exit(cmakeCall.status)
-      }
-    } else {
-      throw err
-    }
-  }
-
-  // Build the Emscripten mobules with ninja
-  console.log('\nRunning ninja...')
-  const ninjaCall = spawnSync('bash', [dockcross, 'ninja', `-C${buildDir}`], {
-    env: process.env,
-    stdio: 'inherit'
-  })
-  if (ninjaCall.status !== 0) {
-    process.exit(ninjaCall.status)
-  }
-  console.log('')
-} // options.buildIo
-
-if (options.copyBuildArtifacts) {
-  try {
-    fs.mkdirSync('dist')
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  try {
-    fs.mkdirSync(path.join('dist', 'image-io'))
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  try {
-    fs.mkdirSync(path.join('dist', 'mesh-io'))
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  try {
-    fs.mkdirSync(path.join('dist', 'dicom', 'public', 'pipelines'), { recursive: true })
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  try {
-    fs.mkdirSync(path.join('dist', 'core', 'web-workers'), { recursive: true })
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  let imageIOFiles = glob.sync(path.join(buildDir, 'image-io', '*.js'))
-  imageIOFiles = imageIOFiles.concat(glob.sync(path.join(buildDir, 'image-io', '*.wasm')))
-  imageIOFiles = imageIOFiles.concat(glob.sync(path.join(buildDir, 'image-io', '*.wasm.zst')))
-  const copyImageIOModules = function (imageIOFile, callback) {
-    const io = path.basename(imageIOFile)
-    const output = path.join('dist', 'image-io', io)
-    fs.copySync(imageIOFile, output)
-    callback(null, io)
-  }
-  const buildImageIOsParallel = function (callback) {
-    console.log('Copying image-io modules...')
-    const result = asyncMod.map(imageIOFiles, copyImageIOModules)
-    callback(null, result)
-  }
-  let meshIOFiles = glob.sync(path.join(buildDir, 'mesh-io', '*.js'))
-  meshIOFiles = meshIOFiles.concat(glob.sync(path.join(buildDir, 'mesh-io', '*.wasm')))
-  meshIOFiles = meshIOFiles.concat(glob.sync(path.join(buildDir, 'mesh-io', '*.wasm.zst')))
-  const copyMeshIOModules = function (meshIOFile, callback) {
-    const io = path.basename(meshIOFile)
-    const output = path.join('dist', 'mesh-io', io)
-    fs.copySync(meshIOFile, output)
-    callback(null, io)
-  }
-  const buildMeshIOsParallel = function (callback) {
-    console.log('Copying mesh-io modules...')
-    const result = asyncMod.map(meshIOFiles, copyMeshIOModules)
-    callback(null, result)
-  }
-  let dicomFiles = glob.sync(path.join(buildDir, 'dicom', '*.js'))
-  dicomFiles = dicomFiles.concat(glob.sync(path.join(buildDir, 'dicom', '*.wasm')))
-  dicomFiles = dicomFiles.concat(glob.sync(path.join(buildDir, 'dicom', '*.wasm.zst')))
-  const copyDICOMModules = function (dicomFile, callback) {
-    const io = path.basename(dicomFile)
-    const output = path.join('dist', 'dicom', 'public', 'pipelines', io)
-    fs.copySync(dicomFile, output)
-    callback(null, io)
-  }
-  const buildDICOMParallel = function (callback) {
-    console.log('Copying dicom modules...')
-    const result = asyncMod.map(dicomFiles, copyDICOMModules)
-    callback(null, result)
-  }
-
-  asyncMod.parallel([
-    buildImageIOsParallel,
-    buildMeshIOsParallel,
-    buildDICOMParallel,
-  ])
-} // options.copySources
-
-const testPipelines = [
-  path.join('test', 'pipelines', 'stdout-stderr-pipeline'),
-  path.join('test', 'pipelines', 'median-filter-pipeline'),
-  path.join('test', 'pipelines', 'input-output-files-pipeline'),
-  path.join('test', 'pipelines', 'input-output-json-pipeline'),
-  path.join('test', 'pipelines', 'mesh-read-write-pipeline'),
-  path.join('test', 'pipelines', 'bindgen-interface-types-pipeline'),
-]
-
-if (options.buildTestPipelines) {
-  const buildPipeline = async (pipelinePath) => {
-    console.log('Building ' + pipelinePath + ' with Emscripten...')
-    let debugFlags = []
-    let buildImage = 'itkwasm/emscripten:latest'
-    if (options.debug) {
-      buildImage = 'itkwasm/emscripten:latest-debug'
-    }
-    if (options.debug) {
-      debugFlags = ['-DCMAKE_BUILD_TYPE:STRING=Debug', "-DCMAKE_EXE_LINKER_FLAGS_DEBUG='-s DISABLE_EXCEPTION_CATCHING=0'"]
-    }
-    const buildPipelineCall = await promiseSpawn('node', [path.join('src', 'itk-wasm-cli.js'), '--image', buildImage, '--source-dir', pipelinePath, 'build', '--'].concat(debugFlags), {
-      env: process.env,
-      stdio: 'inherit'
-    })
-    if (buildPipelineCall.code !== 0) {
-      console.log(buildPipelineCall.stdout)
-      console.error(buildPipelineCall.stderr)
-      process.exit(buildPipelineCall.code)
-    }
-    let pipelineFiles = glob.sync(path.join(pipelinePath, 'emscripten-build', '*.js'))
-    pipelineFiles = pipelineFiles.concat(glob.sync(path.join(pipelinePath, 'emscripten-build', '*.wasm')))
-    pipelineFiles = pipelineFiles.concat(glob.sync(path.join(pipelinePath, 'emscripten-build', '*.wasm.zst')))
-    pipelineFiles.forEach((file) => {
-      const filename = path.basename(file)
-      const output = path.join('dist', 'pipelines', filename)
-      fs.copySync(file, output)
-    })
-  }
-
-  try {
-    fs.mkdirSync(path.join('dist', 'pipelines'))
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  let emscriptenTestPipelines = testPipelines
-  await Promise.all(emscriptenTestPipelines.map(buildPipeline))
-} // options.buildTestPipelines
diff --git a/src/build-wasi.js b/src/build-wasi.js
deleted file mode 100644
index d6beaf7ff..000000000
--- a/src/build-wasi.js
+++ /dev/null
@@ -1,209 +0,0 @@
-#!/usr/bin/env node
-
-import fs from 'fs-extra'
-import path from 'path'
-import { spawnSync } from 'child_process'
-import glob from 'glob'
-import asyncMod from 'async'
-import promiseSpawn from '@npmcli/promise-spawn'
-
-import { Command } from 'commander/esm.mjs'
-
-const program = new Command()
-
-program
-  .option('-b, --no-build-io', 'Do not compile io modules')
-  .option('-s, --no-copy-build-artifacts', 'Do not copy build artifacts')
-  .option('-w, --no-build-test-pipelines', 'Do not build the wasi test pipelines')
-  .option('-d, --debug', 'Create a debug build of the WebAssembly modules')
-  .parse(process.argv)
-
-const options = program.opts()
-
-// Make the directory to hold build artifacts
-const buildDir = 'build-wasi'
-try {
-  fs.mkdirSync(buildDir)
-} catch (err) {
-  if (err.code !== 'EEXIST') throw err
-}
-
-if (options.buildIo) {
-  const dockerVersion = spawnSync('docker', ['--version'], {
-    env: process.env,
-    stdio: ['ignore', 'ignore', 'ignore']
-  })
-  if (dockerVersion.status !== 0) {
-    console.error("Could not run the 'docker' command.")
-    console.error('This package requires Docker to build.')
-    console.error('')
-    console.error('Please find installation instructions at:')
-    console.error('')
-    console.error('  https://docs.docker.com/install/')
-    console.error('')
-    process.exit(dockerVersion.status)
-  }
-
-  // Ensure we have the 'dockcross' Docker build environment driver script
-  let dockcross = `${buildDir}/dockcross`
-  if (options.debug) {
-    dockcross = `${buildDir}/dockcross-debug`
-  }
-  try {
-    fs.statSync(dockcross)
-  } catch (err) {
-    if (err.code === 'ENOENT') {
-      const output = fs.openSync(dockcross, 'w')
-      let buildImage = 'itkwasm/wasi:latest'
-      if (options.debug) {
-        buildImage = 'itkwasm/wasi:latest-debug'
-      }
-      const dockerCall = spawnSync('docker', ['run', '--rm', buildImage], {
-        env: process.env,
-        stdio: ['ignore', output, null]
-      })
-      if (dockerCall.status !== 0) {
-        process.exit(dockerCall.status)
-      }
-      fs.closeSync(output)
-      fs.chmodSync(dockcross, '755')
-    } else {
-      throw err
-    }
-  }
-
-  // Perform initial CMake configuration if required
-  try {
-    fs.statSync(path.join(buildDir, 'build.ninja'))
-  } catch (err) {
-    if (err.code === 'ENOENT') {
-      let buildType = '-DCMAKE_BUILD_TYPE:STRING=Release'
-      if (options.debug) {
-        buildType = '-DCMAKE_BUILD_TYPE:STRING=Debug'
-      }
-      const cmakeCall = spawnSync('bash', [dockcross, 'bash', '-c', `cmake ${buildType} -B${buildDir} -H. -GNinja -DSIZEOF_SIZE_T:INTERNAL=4 -DSANITIZE:BOOL=OFF -DITK_DIR=/ITK-build -DITK_WASM_NO_INTERFACE_LINK=1 -DBUILD_ITK_WASM_IO_MODULES=ON`], {
-        env: process.env,
-        stdio: 'inherit'
-      })
-      if (cmakeCall.status !== 0) {
-        process.exit(cmakeCall.status)
-      }
-    } else {
-      throw err
-    }
-  }
-
-  // Build the WebAssembly mobules with ninja
-  console.log('\nRunning ninja...')
-  const ninjaCall = spawnSync('bash', [dockcross, 'ninja', `-C${buildDir}`], {
-    env: process.env,
-    stdio: 'inherit'
-  })
-  if (ninjaCall.status !== 0) {
-    process.exit(ninjaCall.status)
-  }
-  console.log('')
-} // options.buildIo
-
-if (options.copyBuildArtifacts) {
-  try {
-    fs.mkdirSync('dist')
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  try {
-    fs.mkdirSync(path.join('dist', 'wasi-image-io'))
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  try {
-    fs.mkdirSync(path.join('dist', 'wasi-mesh-io'))
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  let imageIOFiles = glob.sync(path.join(buildDir, 'wasi-image-io', '*.wasm'))
-  const copyImageIOModules = function (imageIOFile, callback) {
-    const io = path.basename(imageIOFile)
-    const output = path.join('dist', 'wasi-image-io', io)
-    fs.copySync(imageIOFile, output)
-    callback(null, io)
-  }
-  const buildImageIOsParallel = function (callback) {
-    console.log('Copying wasi-image-io modules...')
-    const result = asyncMod.map(imageIOFiles, copyImageIOModules)
-    callback(null, result)
-  }
-  let meshIOFiles = glob.sync(path.join(buildDir, 'wasi-mesh-io', '*.wasm'))
-  const copyMeshIOModules = function (meshIOFile, callback) {
-    const io = path.basename(meshIOFile)
-    const output = path.join('dist', 'wasi-mesh-io', io)
-    fs.copySync(meshIOFile, output)
-    callback(null, io)
-  }
-  const buildMeshIOsParallel = function (callback) {
-    console.log('Copying wasi-mesh-io modules...')
-    const result = asyncMod.map(meshIOFiles, copyMeshIOModules)
-    callback(null, result)
-  }
-  let dicomFiles = glob.sync(path.join(buildDir, 'wasi-dicom', '*.wasm'))
-  const copyDICOMModules = function (dicomFile, callback) {
-    const io = path.basename(dicomFile)
-    const output = path.join('dist', 'wasi-dicom', io)
-    fs.copySync(dicomFile, output)
-    callback(null, io)
-  }
-  const buildDICOMParallel = function (callback) {
-    console.log('Copying wasi-dicom modules...')
-    const result = asyncMod.map(dicomFiles, copyDICOMModules)
-    callback(null, result)
-  }
-
-  asyncMod.parallel([
-    buildImageIOsParallel,
-    buildMeshIOsParallel,
-    buildDICOMParallel,
-  ])
-} // options.copySources
-
-const testPipelines = [
-  path.join('test', 'pipelines', 'stdout-stderr-pipeline'),
-  path.join('test', 'pipelines', 'median-filter-pipeline'),
-  path.join('test', 'pipelines', 'input-output-files-pipeline'),
-  path.join('test', 'pipelines', 'input-output-json-pipeline'),
-  path.join('test', 'pipelines', 'mesh-read-write-pipeline'),
-  path.join('test', 'pipelines', 'bindgen-interface-types-pipeline'),
-]
-
-if (options.buildTestPipelines) {
-  const buildPipeline = async (pipelinePath) => {
-    console.log('Building ' + pipelinePath + ' with wasi...')
-    let debugFlags = []
-    let buildImage = 'itkwasm/wasi:latest'
-    if (options.debug) {
-      debugFlags = ['-DCMAKE_BUILD_TYPE:STRING=Debug']
-      buildImage = 'itkwasm/wasi:latest-debug'
-    }
-    const buildPipelineCall = await promiseSpawn('node', [path.join('src', 'itk-wasm-cli.js'), '--image', buildImage, '--build-dir', 'wasi-build', '--source-dir', pipelinePath, 'build', '--'].concat(debugFlags), {
-      env: process.env,
-      stdio: 'inherit'
-    })
-    if (buildPipelineCall.code !== 0) {
-      console.log(buildPipelineCall.stdout)
-      console.error(buildPipelineCall.stderr)
-      process.exit(buildPipelineCall.code)
-    }
-    const pipelineFiles = glob.sync(path.join(pipelinePath, 'wasi-build', '*.wasm'))
-    pipelineFiles.forEach((file) => {
-      const filename = path.basename(file)
-      const output = path.join('dist', 'pipelines', filename)
-      fs.copySync(file, output)
-    })
-  }
-
-  try {
-    fs.mkdirSync(path.join('dist', 'pipelines'))
-  } catch (err) {
-    if (err.code !== 'EEXIST') throw err
-  }
-  await Promise.all(testPipelines.map(buildPipeline))
-} // options.buildWasiPipelines
diff --git a/src/core/CastImageOptions.ts b/src/core/CastImageOptions.ts
deleted file mode 100644
index 06b3e990a..000000000
--- a/src/core/CastImageOptions.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import IntTypes from './interface-types/int-types.js'
-import FloatTypes from './interface-types/float-types.js'
-import PixelTypes from './interface-types/pixel-types.js'
-
-interface CastImageOptions {
-  /** Component type, from itk-wasm IntTypes, FloatTypes, for the output pixel components. Defaults to the input component type. */
-  componentType?: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes]
-
-  /** Pixel type, from itk-wasm PixelTypes, for the output pixels. Defaults to the input pixel type. */
-  pixelType?: typeof PixelTypes[keyof typeof PixelTypes]
-}
-
-export default CastImageOptions
diff --git a/src/core/IOTypes.ts b/src/core/IOTypes.ts
deleted file mode 100644
index e29cfc78f..000000000
--- a/src/core/IOTypes.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-const IOTypes = {
-  Text: 'Text',
-  Binary: 'Binary',
-  Image: 'Image',
-  Mesh: 'Mesh'
-} as const
-
-export default IOTypes
diff --git a/src/core/ITKWasmEmscriptenModule.ts b/src/core/ITKWasmEmscriptenModule.ts
deleted file mode 100644
index 1ad8f9ecc..000000000
--- a/src/core/ITKWasmEmscriptenModule.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/// <reference types="emscripten" />
-
-interface ITKWasmEmscriptenModule extends EmscriptenModule {
-  mountContainingDir: (filePath: string) => string
-  unmountContainingDir: (filePath: string) => void
-  mountDir: (filePath: string) => string
-  unmountDir: (filePath: string) => void
-
-  fs_mkdirs: (dirs: string) => void
-  fs_readFile: (path: string, opts: { encoding?: string, flags?: string }) => string | Uint8Array
-  fs_writeFile: (path: string, data: string | ArrayBufferView, opts?: { flags?: string }) => void
-  fs_unlink: (path: string) => void
-  fs_open: (path: string, flags: string, mode?: string) => object
-  fs_stat: (path: string) => { size: number }
-  fs_close: (stream: object) => void
-  fs_read: (stream: object, buffer: ArrayBufferView, offset: number, length: number, position?: number) => void
-}
-
-export default ITKWasmEmscriptenModule
diff --git a/src/core/InterfaceTypes.ts b/src/core/InterfaceTypes.ts
deleted file mode 100644
index bcf31e06f..000000000
--- a/src/core/InterfaceTypes.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-const InterfaceTypes = {
-  // Todo: remove Interface prefix after IOTypes has been removed
-  TextFile: 'InterfaceTextFile',
-  BinaryFile: 'InterfaceBinaryFile',
-  TextStream: 'InterfaceTextStream',
-  BinaryStream: 'InterfaceBinaryStream',
-  Image: 'InterfaceImage',
-  Mesh: 'InterfaceMesh',
-  PolyData: 'InterfacePolyData',
-  JsonCompatible: 'InterfaceJsonCompatible'
-} as const
-
-export default InterfaceTypes
diff --git a/src/core/TypedArray.ts b/src/core/TypedArray.ts
deleted file mode 100644
index daffb6020..000000000
--- a/src/core/TypedArray.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | BigInt64Array | BigUint64Array
-
-export default TypedArray
diff --git a/src/core/WorkerPool.ts b/src/core/WorkerPool.ts
deleted file mode 100644
index 28aead9db..000000000
--- a/src/core/WorkerPool.ts
+++ /dev/null
@@ -1,167 +0,0 @@
-/* eslint-disable  @typescript-eslint/no-non-null-assertion */
-
-import WorkerPoolFunction from './WorkerPoolFunction.js'
-import WorkerPoolProgressCallback from './WorkerPoolProgressCallback.js'
-import WorkerPoolRunTasksResult from './WorkerPoolRunTasksResult.js'
-
-interface RunInfo {
-  taskQueue: any[]
-  results: any[]
-  addingTasks: boolean
-  postponed: boolean
-  runningWorkers: number
-  index: number
-  completedTasks: number
-  progressCallback: WorkerPoolProgressCallback | null
-  canceled: boolean | null
-  resolve?: (results: any) => void
-  reject?: (error: any) => void
-}
-
-class WorkerPool {
-  fcn: WorkerPoolFunction
-
-  workerQueue: Array<Worker | null>
-
-  runInfo: RunInfo[]
-
-  /* poolSize is the maximum number of web workers to create in the pool.
-   *
-   * The function, fcn, should accept null or an existing worker as its first argument.
-   * It most also return and object with the used worker on the `webWorker`
-   * property.  * Example: runPipeline.
-   *
-   **/
-  constructor (poolSize: number, fcn: WorkerPoolFunction) {
-    this.fcn = fcn
-
-    this.workerQueue = new Array(poolSize)
-    this.workerQueue.fill(null)
-
-    this.runInfo = []
-  }
-
-  /*
-   * Run the tasks specified by the arguments in the taskArgsArray that will
-   * be passed to the pool fcn.
-   *
-   * An optional progressCallback will be called with the number of complete
-   * tasks and the total number of tasks as arguments every time a task has
-   * completed.
-   *
-   * Returns an object containing a promise ('promise') to communicate results
-   * as well as an id ('runId') which can be used to cancel any remaining pending
-   * tasks before they complete.
-   */
-  public runTasks (taskArgsArray: any[], progressCallback: WorkerPoolProgressCallback | null = null): WorkerPoolRunTasksResult {
-    const info: RunInfo = {
-      taskQueue: [],
-      results: [],
-      addingTasks: false,
-      postponed: false,
-      runningWorkers: 0,
-      index: 0,
-      completedTasks: 0,
-      progressCallback: progressCallback,
-      canceled: false
-    }
-    this.runInfo.push(info)
-    info.index = this.runInfo.length - 1
-    return {
-      promise: new Promise((resolve, reject) => {
-        info.resolve = resolve
-        info.reject = reject
-
-        info.results = new Array(taskArgsArray.length)
-        info.completedTasks = 0
-
-        info.addingTasks = true
-        taskArgsArray.forEach((taskArg, index) => {
-          this.addTask(info.index, index, taskArg)
-        })
-        info.addingTasks = false
-      }),
-      runId: info.index
-    }
-  }
-
-  public terminateWorkers (): void {
-    for (let index = 0; index < this.workerQueue.length; index++) {
-      const worker = this.workerQueue[index]
-      if (worker != null) {
-        worker.terminate()
-      }
-      this.workerQueue[index] = null
-    }
-  }
-
-  public cancel (runId: number): void {
-    const info = this.runInfo[runId]
-    if (info !== null && info !== undefined) {
-      info.canceled = true
-    }
-  }
-
-  private addTask (infoIndex: number, resultIndex: number, taskArgs: []): void {
-    const info = this.runInfo[infoIndex]
-
-    if (info?.canceled === true) {
-      info.reject!('Remaining tasks canceled')
-      this.clearTask(info.index)
-      return
-    }
-
-    if (this.workerQueue.length > 0) {
-      const worker = this.workerQueue.pop() as Worker | null
-      info.runningWorkers++
-      this.fcn(worker, ...taskArgs).then(({ webWorker, ...result }) => {
-        this.workerQueue.push(webWorker)
-        // Check if this task was canceled while it was getting done
-        if (this.runInfo[infoIndex] !== null) {
-          info.runningWorkers--
-          info.results[resultIndex] = result
-          info.completedTasks++
-          if (info.progressCallback != null) {
-            info.progressCallback(info.completedTasks, info.results.length)
-          }
-
-          if (info.taskQueue.length > 0) {
-            const reTask = info.taskQueue.shift() as any[]
-            this.addTask(infoIndex, reTask[0], reTask[1])
-          } else if (!info.addingTasks && info.runningWorkers === 0) {
-            const results = info.results
-            info.resolve!(results)
-            this.clearTask(info.index)
-          }
-        }
-      }).catch((error) => {
-        info.reject!(error)
-        this.clearTask(info.index)
-      })
-    } else {
-      if (info.runningWorkers !== 0 || info.postponed) {
-        // At least one worker is working on these tasks, and it will pick up
-        // the next item in the taskQueue when done.
-        info.taskQueue.push([resultIndex, taskArgs])
-      } else {
-        // Try again later.
-        info.postponed = true
-        setTimeout(() => {
-          info.postponed = false
-          this.addTask(info.index, resultIndex, taskArgs)
-        }, 50)
-      }
-    }
-  }
-
-  private clearTask (clearIndex: number): void {
-    this.runInfo[clearIndex].results = []
-    this.runInfo[clearIndex].taskQueue = []
-    this.runInfo[clearIndex].progressCallback = null
-    this.runInfo[clearIndex].canceled = null
-    this.runInfo[clearIndex].reject = () => {}
-    this.runInfo[clearIndex].resolve = () => {}
-  }
-}
-
-export default WorkerPool
diff --git a/src/core/WorkerPoolFunction.ts b/src/core/WorkerPoolFunction.ts
deleted file mode 100644
index 93f220f6a..000000000
--- a/src/core/WorkerPoolFunction.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface WorkerPoolFunctionResult { webWorker: Worker }
-
-type WorkerPoolFunction = (webWorker: Worker | null, ...args: any[]) => Promise<WorkerPoolFunctionResult>
-
-export default WorkerPoolFunction
diff --git a/src/core/WorkerPoolProgressCallback.ts b/src/core/WorkerPoolProgressCallback.ts
deleted file mode 100644
index f2a128111..000000000
--- a/src/core/WorkerPoolProgressCallback.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-type WorkerPoolProgressCallback = (completedTasks: number, totalTasks: number) => void
-
-export default WorkerPoolProgressCallback
diff --git a/src/core/WorkerPoolRunTasksResult.ts b/src/core/WorkerPoolRunTasksResult.ts
deleted file mode 100644
index 36253c216..000000000
--- a/src/core/WorkerPoolRunTasksResult.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-interface WorkerPoolRunTasksResult {
-  promise: Promise<any[]>
-  runId: number
-}
-
-export default WorkerPoolRunTasksResult
diff --git a/src/core/bufferToTypedArray.ts b/src/core/bufferToTypedArray.ts
deleted file mode 100644
index c4e37f3c9..000000000
--- a/src/core/bufferToTypedArray.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import IntTypes from './interface-types/int-types.js'
-import FloatTypes from './interface-types/float-types.js'
-import type TypedArray from './TypedArray.js'
-
-function bufferToTypedArray (wasmType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] | 'null' | null, buffer: ArrayBuffer): null | TypedArray {
-  let typedArray: null | TypedArray = null
-  switch (wasmType) {
-    case IntTypes.UInt8: {
-      typedArray = new Uint8Array(buffer)
-      break
-    }
-    case IntTypes.Int8: {
-      typedArray = new Int8Array(buffer)
-      break
-    }
-    case IntTypes.UInt16: {
-      typedArray = new Uint16Array(buffer)
-      break
-    }
-    case IntTypes.Int16: {
-      typedArray = new Int16Array(buffer)
-      break
-    }
-    case IntTypes.UInt32: {
-      typedArray = new Uint32Array(buffer)
-      break
-    }
-    case IntTypes.Int32: {
-      typedArray = new Int32Array(buffer)
-      break
-    }
-    case IntTypes.UInt64: {
-      if (typeof globalThis.BigUint64Array === 'function') {
-        typedArray = new BigUint64Array(buffer)
-      } else {
-        // Sub with reasonable default. Will get cast to Uint8Array when
-        // transferred to WebAssembly.
-        typedArray = new Uint8Array(buffer)
-      }
-      break
-    }
-    case IntTypes.Int64: {
-      if (typeof globalThis.BigInt64Array === 'function') {
-        typedArray = new BigInt64Array(buffer)
-      } else {
-        // Sub with reasonable default. Will get cast to Uint8Array when
-        // transferred to WebAssembly.
-        typedArray = new Uint8Array(buffer)
-      }
-      break
-    }
-    case FloatTypes.Float32: {
-      typedArray = new Float32Array(buffer)
-      break
-    }
-    case FloatTypes.Float64: {
-      typedArray = new Float64Array(buffer)
-      break
-    }
-    case 'null': {
-      typedArray = null
-      break
-    }
-    case null: {
-      typedArray = null
-      break
-    }
-    default:
-      throw new Error('Type is not supported as a TypedArray')
-  }
-
-  return typedArray
-}
-
-export default bufferToTypedArray
diff --git a/src/core/castImage.ts b/src/core/castImage.ts
deleted file mode 100644
index 47caf291a..000000000
--- a/src/core/castImage.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-import Image from './interface-types/image.js'
-import CastImageOptions from './CastImageOptions.js'
-import PixelTypes from './interface-types/pixel-types.js'
-import IntTypes from './interface-types/int-types.js'
-import FloatTypes from './interface-types/float-types.js'
-
-/**
- * Cast an image to another PixelType and/or ComponentType
- *
- * @param {Image} image - The input image
- * @param {CastImageOptions} options - specify the componentType and/or pixelType of the output
- */
-function castImage (inputImage: Image, options?: CastImageOptions): Image {
-  const outputImageType = { ...inputImage.imageType }
-
-  if (typeof options !== 'undefined' && typeof options.pixelType !== 'undefined') {
-    outputImageType.pixelType = options.pixelType
-    if (options.pixelType === PixelTypes.Scalar && outputImageType.components !== 1) {
-      throw new Error('Cannot cast multi-component image to a scalar image')
-    }
-  }
-  if (typeof options !== 'undefined' && typeof options.componentType !== 'undefined' && options.componentType !== inputImage.imageType.componentType) {
-    outputImageType.componentType = options.componentType
-  }
-
-  const outputImage = new Image(outputImageType)
-
-  outputImage.name = inputImage.name
-  outputImage.origin = Array.from(inputImage.origin)
-  outputImage.spacing = Array.from(inputImage.spacing)
-  outputImage.direction = inputImage.direction.slice()
-  outputImage.size = Array.from(inputImage.size)
-  // Deep copy the map
-  outputImage.metadata = new Map(JSON.parse(JSON.stringify(Array.from(inputImage.metadata))))
-
-  if (inputImage.data !== null) {
-    if (typeof options !== 'undefined' && typeof options.componentType !== 'undefined' && options.componentType !== inputImage.imageType.componentType) {
-      switch (inputImage.imageType.componentType) {
-        case IntTypes.UInt8:
-        case IntTypes.Int8:
-        case IntTypes.UInt16:
-        case IntTypes.Int16:
-        case IntTypes.UInt32:
-        case IntTypes.Int32:
-        case FloatTypes.Float32:
-        case FloatTypes.Float64:
-          switch (outputImage.imageType.componentType) {
-            case IntTypes.UInt8:
-              outputImage.data = new Uint8Array(inputImage.data)
-              break
-            case IntTypes.Int8:
-              outputImage.data = new Int8Array(inputImage.data)
-              break
-            case IntTypes.UInt16:
-              outputImage.data = new Uint16Array(inputImage.data)
-              break
-            case IntTypes.Int16:
-              outputImage.data = new Int16Array(inputImage.data)
-              break
-            case IntTypes.UInt32:
-              outputImage.data = new Uint32Array(inputImage.data)
-              break
-            case IntTypes.Int32:
-              outputImage.data = new Int32Array(inputImage.data)
-              break
-            case FloatTypes.Float32:
-              outputImage.data = new Float32Array(inputImage.data)
-              break
-            case FloatTypes.Float64:
-              outputImage.data = new Float64Array(inputImage.data)
-              break
-            case IntTypes.UInt64:
-              outputImage.data = new BigUint64Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = BigInt.asIntN(64, BigInt(inputImage.data[idx]))
-              }
-              break
-            case IntTypes.Int64:
-              outputImage.data = new BigInt64Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = BigInt.asUintN(64, BigInt(inputImage.data[idx]))
-              }
-              break
-          }
-          break
-        case IntTypes.UInt64:
-        case IntTypes.Int64:
-          switch (outputImage.imageType.componentType) {
-            case IntTypes.UInt8:
-              outputImage.data = new Uint8Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case IntTypes.Int8:
-              outputImage.data = new Int8Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case IntTypes.UInt16:
-              outputImage.data = new Uint16Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case IntTypes.Int16:
-              outputImage.data = new Int16Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case IntTypes.UInt32:
-              outputImage.data = new Uint32Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case IntTypes.Int32:
-              outputImage.data = new Int32Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case FloatTypes.Float32:
-              outputImage.data = new Float32Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case FloatTypes.Float64:
-              outputImage.data = new Float64Array(inputImage.data.length)
-              for (let idx = 0; idx < outputImage.data.length; idx++) {
-                outputImage.data[idx] = Number(inputImage.data[idx])
-              }
-              break
-            case IntTypes.UInt64:
-              outputImage.data = new BigUint64Array(inputImage.data)
-              break
-            case IntTypes.Int64:
-              outputImage.data = new BigInt64Array(inputImage.data)
-              break
-          }
-          break
-      }
-    } else {
-      // copy
-      const CTor = inputImage.data.constructor as new(length: number) => typeof inputImage.data
-      outputImage.data = new CTor(inputImage.data.length)
-      if (outputImage.data != null) {
-        // @ts-expect-error: error TS2345: Argument of type 'TypedArray' is not assignable to parameter of type 'ArrayLike<number> & ArrayLike<bigint>'
-        outputImage.data.set(inputImage.data, 0)
-      }
-    }
-  }
-
-  return outputImage
-}
-
-export default castImage
diff --git a/src/core/copyImage.ts b/src/core/copyImage.ts
deleted file mode 100644
index 8a91f8edb..000000000
--- a/src/core/copyImage.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import Image from './interface-types/image.js'
-
-function copyImage (image: Image): Image {
-  const copy = new Image(image.imageType)
-  copy.name = image.name
-
-  copy.origin = Array.from(image.origin)
-  copy.spacing = Array.from(image.spacing)
-  copy.direction = image.direction.slice()
-
-  copy.size = Array.from(image.size)
-
-  if (image.data !== null) {
-    const CTor = image.data.constructor as new(length: number) => typeof image.data
-    copy.data = new CTor(image.data.length)
-    if (copy.data != null) {
-      // @ts-expect-error: error TS2345: Argument of type 'TypedArray' is not assignable to parameter of type 'ArrayLike<number> & ArrayLike<bigint>'
-      copy.data.set(image.data, 0)
-    }
-  }
-
-  return copy
-}
-
-export default copyImage
diff --git a/src/core/create-worker-proxy.ts b/src/core/create-worker-proxy.ts
deleted file mode 100644
index 73cb78388..000000000
--- a/src/core/create-worker-proxy.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import axios from 'axios'
-import * as Comlink from 'comlink'
-
-import WorkerProxy from './web-workers/worker-proxy.js'
-import config from '../itkConfig.js'
-
-interface ItkWorker extends Worker {
-  workerProxy: WorkerProxy
-  originalTerminate: () => void
-}
-
-interface createWorkerProxyResult {
-  workerProxy: WorkerProxy
-  worker: ItkWorker
-}
-
-function workerToWorkerProxy (worker: Worker): createWorkerProxyResult {
-  const workerProxy = Comlink.wrap(worker) as WorkerProxy
-  const itkWebWorker = worker as ItkWorker
-  itkWebWorker.workerProxy = workerProxy
-  itkWebWorker.originalTerminate = itkWebWorker.terminate
-  itkWebWorker.terminate = () => {
-    itkWebWorker.workerProxy[Comlink.releaseProxy]()
-    itkWebWorker.originalTerminate()
-  }
-  return { workerProxy, worker: itkWebWorker }
-}
-
-// Internal function to create a web worker promise
-async function createWorkerProxy (existingWorker: Worker | null, pipelineWorkerUrl?: string | null): Promise<createWorkerProxyResult> {
-  let workerProxy: WorkerProxy
-  if (existingWorker != null) {
-    // See if we have a worker promise attached the worker, if so reuse it. This ensures
-    // that we can safely reuse the worker without issues.
-    const itkWebWorker = existingWorker as ItkWorker
-    if (itkWebWorker.workerProxy !== undefined) {
-      workerProxy = itkWebWorker.workerProxy
-      return { workerProxy, worker: itkWebWorker }
-    } else {
-      return workerToWorkerProxy(existingWorker)
-    }
-  }
-
-  const workerUrl = typeof pipelineWorkerUrl === 'undefined' ? config.pipelineWorkerUrl : pipelineWorkerUrl
-  let worker = null
-  // @ts-expect-error: error TS2339: Property 'webWorkersUrl' does not exist on type '{ pipelineWorkerUrl: string; imageIOUrl: string; meshIOUrl: string; pipelinesUrl: string; }
-  const webWorkersUrl = config.webWorkersUrl
-  if (typeof webWorkersUrl !== 'undefined') {
-    console.warn('itkConfig webWorkersUrl is deprecated. Please use pipelineWorkerUrl with the full path to the pipeline worker.')
-    const min = 'min.'
-    // debug
-    // const min = ''
-
-    const webWorkerString = webWorkersUrl as string
-    if (webWorkerString.startsWith('http')) {
-      const response = await axios.get(`${webWorkerString}/bundles/pipeline.${min}worker.js`, { responseType: 'blob' })
-      const workerObjectUrl = URL.createObjectURL(response.data as Blob)
-      worker = new Worker(workerObjectUrl, { type: 'module' })
-    } else {
-      worker = new Worker(`${webWorkerString}/bundles/pipeline.${min}worker.js`, { type: 'module' })
-    }
-  } else if (workerUrl === null) {
-    // Use the version built with the bundler
-    //
-    // Bundlers, e.g. WebPack, Vite, Rollup, see these paths at build time
-    worker = new Worker(new URL('./web-workers/itk-wasm-pipeline.worker.js', import.meta.url), { type: 'module' })
-  } else {
-    if (workerUrl.startsWith('http')) {
-      const response = await axios.get(workerUrl, { responseType: 'blob' })
-      const workerObjectUrl = URL.createObjectURL(response.data as Blob)
-      worker = new Worker(workerObjectUrl, { type: 'module' })
-    } else {
-      worker = new Worker(workerUrl, { type: 'module' })
-    }
-  }
-
-  return workerToWorkerProxy(worker)
-}
-
-export default createWorkerProxy
diff --git a/src/core/get-transferables.ts b/src/core/get-transferables.ts
deleted file mode 100644
index 8a216bdb6..000000000
--- a/src/core/get-transferables.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-const haveSharedArrayBuffer = typeof globalThis.SharedArrayBuffer !== 'undefined' // eslint-disable-line
-
-function getTransferables (data?: any[] | null): ArrayBuffer[] {
-  if (data === undefined || data === null) {
-    return []
-  }
-  const transferables: ArrayBuffer[] = []
-  for (let i = 0; i < data.length; i++) {
-    const transferable = getTransferable(data[i])
-    if (transferable !== null) {
-      transferables.push(transferable)
-    }
-  }
-  return transferables
-}
-
-function getTransferable (data?: any): ArrayBuffer | null {
-  if (data === undefined || data === null) {
-    return null
-  }
-  let result: null | ArrayBuffer = null
-  if (data.buffer !== undefined) {
-    result = data.buffer as ArrayBuffer
-  } else if (data.byteLength !== undefined) {
-    result = data as ArrayBuffer
-  }
-  if (haveSharedArrayBuffer && result instanceof SharedArrayBuffer) { // eslint-disable-line
-    return null
-  }
-  return result
-}
-
-export default getTransferables
diff --git a/src/core/getMatrixElement.ts b/src/core/getMatrixElement.ts
deleted file mode 100644
index 553fb3a01..000000000
--- a/src/core/getMatrixElement.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import TypedArray from './TypedArray.js'
-
-function getMatrixElement (matrixData: TypedArray, columns: number, row: number, column: number): number | bigint {
-  return matrixData[column + row * columns]
-}
-
-export default getMatrixElement
diff --git a/src/core/imageSharedBufferOrCopy.ts b/src/core/imageSharedBufferOrCopy.ts
deleted file mode 100644
index 76a4e3e75..000000000
--- a/src/core/imageSharedBufferOrCopy.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import copyImage from './copyImage.js'
-import Image from './interface-types/image.js'
-
-const haveSharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function'
-
-/** If SharedArrayBuffer's are available, ensure an itk.Image's buffer is a
- * SharedArrayBuffer. If SharedArrayBuffer's are not available, return a copy.
- * */
-function imageSharedBufferOrCopy (image: Image): Image {
-  if (image.data === null) {
-    return image
-  }
-  if (haveSharedArrayBuffer) {
-    if (image.data.buffer instanceof SharedArrayBuffer) { // eslint-disable-line
-      return image
-    }
-
-    const sharedBuffer = new SharedArrayBuffer(image.data.buffer.byteLength) // eslint-disable-line
-    const CTor = image.data.constructor as new(buffer: SharedArrayBuffer) => typeof image.data
-    const sharedTypedArray = new CTor(sharedBuffer)
-    if (sharedTypedArray !== null) {
-      // @ts-expect-error: error TS2345: Argument of type 'TypedArray' is not assignable to parameter of type 'ArrayLike<number> & ArrayLike<bigint>'.
-
-      sharedTypedArray.set(image.data, 0)
-    }
-    image.data = sharedTypedArray
-    return image
-  } else {
-    return copyImage(image)
-  }
-}
-
-export default imageSharedBufferOrCopy
diff --git a/src/core/index.ts b/src/core/index.ts
deleted file mode 100644
index 3d9c4a94f..000000000
--- a/src/core/index.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-// Core API interfaces, data structures, and functions
-
-export { default as itkConfig } from '../itkConfig.js'
-export { default as version } from './version.js'
-
-export { default as InterfaceTypes } from './InterfaceTypes.js'
-
-export { default as TextStream } from './interface-types/text-stream.js'
-export { default as BinaryStream } from './interface-types/binary-stream.js'
-export { default as TextFile } from './interface-types/text-file.js'
-export { default as BinaryFile } from './interface-types/binary-file.js'
-export { default as JsonCompatible } from './interface-types/json-compatible.js'
-
-export { default as TypedArray } from './TypedArray.js'
-
-export { default as IntTypes } from './interface-types/int-types.js'
-export { default as FloatTypes } from './interface-types/float-types.js'
-export { default as Metadata } from './interface-types/metadata.js'
-
-export { default as IOTypes } from './IOTypes.js'
-
-export { default as PixelTypes } from './interface-types/pixel-types.js'
-
-export { default as getMatrixElement } from './getMatrixElement.js'
-export { default as setMatrixElement } from './setMatrixElement.js'
-
-export { default as Image } from './interface-types/image.js'
-export { default as ImageType } from './interface-types/image-type.js'
-
-export { default as Mesh } from './interface-types/mesh.js'
-export { default as MeshType } from './interface-types/mesh-type.js'
-
-export { default as PolyData } from './interface-types/poly-data.js'
-export { default as PolyDataType } from './interface-types/poly-data-type.js'
-
-export { default as bufferToTypedArray } from './bufferToTypedArray.js'
-export { default as copyImage } from './copyImage.js'
-export { default as stackImages } from './stackImages.js'
-export { default as imageSharedBufferOrCopy } from './imageSharedBufferOrCopy.js'
-export { default as CastImageOptions } from './CastImageOptions.js'
-export { default as castImage } from './castImage.js'
-
-export { default as WorkerPool } from './WorkerPool.js'
-export { default as WorkerPoolFunction } from './WorkerPoolFunction.js'
-export { default as WorkerPoolProgressCallback } from './WorkerPoolProgressCallback.js'
-export { default as WorkerPoolRunTasksResult } from './WorkerPoolRunTasksResult.js'
-export { default as getTransferables } from './get-transferables.js'
-export { default as createWorkerProxy } from './create-worker-proxy.js'
diff --git a/src/core/interface-types/binary-file.ts b/src/core/interface-types/binary-file.ts
deleted file mode 100644
index a45103b81..000000000
--- a/src/core/interface-types/binary-file.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-interface BinaryFile {
-  data: Uint8Array
-  path: string
-}
-
-export default BinaryFile
diff --git a/src/core/interface-types/binary-stream.ts b/src/core/interface-types/binary-stream.ts
deleted file mode 100644
index a0604c085..000000000
--- a/src/core/interface-types/binary-stream.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface BinaryStream {
-  data: Uint8Array
-}
-
-export default BinaryStream
diff --git a/src/core/interface-types/float-types.ts b/src/core/interface-types/float-types.ts
deleted file mode 100644
index def02aff2..000000000
--- a/src/core/interface-types/float-types.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-const FloatTypes = {
-  Float32: 'float32',
-  Float64: 'float64',
-
-  SpacePrecisionType: 'float64'
-} as const
-
-export default FloatTypes
diff --git a/src/core/interface-types/image-type.ts b/src/core/interface-types/image-type.ts
deleted file mode 100644
index 2b3654d35..000000000
--- a/src/core/interface-types/image-type.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import IntTypes from './int-types.js'
-import FloatTypes from './float-types.js'
-import PixelTypes from './pixel-types.js'
-
-class ImageType {
-  constructor (
-    public readonly dimension: number = 2,
-    public readonly componentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = IntTypes.UInt8,
-    public readonly pixelType: typeof PixelTypes[keyof typeof PixelTypes] = PixelTypes.Scalar,
-    public readonly components: number = 1
-  ) {}
-}
-
-export default ImageType
diff --git a/src/core/interface-types/image.ts b/src/core/interface-types/image.ts
deleted file mode 100644
index 3f98ce61c..000000000
--- a/src/core/interface-types/image.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import ImageType from './image-type.js'
-import type TypedArray from '../TypedArray.js'
-import setMatrixElement from '../setMatrixElement.js'
-import Metadata from './metadata.js'
-
-class Image {
-  name: string = 'image'
-
-  origin: number[]
-
-  spacing: number[]
-
-  direction: TypedArray
-
-  size: number[]
-
-  metadata: Metadata
-
-  data: null | TypedArray
-
-  constructor (public readonly imageType = new ImageType()) {
-    const dimension = imageType.dimension
-    this.origin = new Array(dimension)
-    this.origin.fill(0.0)
-
-    this.spacing = new Array(dimension)
-    this.spacing.fill(1.0)
-
-    this.direction = new Float64Array(dimension * dimension)
-    this.direction.fill(0.0)
-    for (let ii = 0; ii < dimension; ii++) {
-      setMatrixElement(this.direction, dimension, ii, ii, 1.0)
-    }
-
-    this.size = new Array(dimension)
-    this.size.fill(0)
-
-    this.metadata = new Map()
-
-    this.data = null
-  }
-}
-
-export default Image
diff --git a/src/core/interface-types/int-types.ts b/src/core/interface-types/int-types.ts
deleted file mode 100644
index c2aecbada..000000000
--- a/src/core/interface-types/int-types.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-const IntTypes = {
-  Int8: 'int8',
-  UInt8: 'uint8',
-  Int16: 'int16',
-  UInt16: 'uint16',
-  Int32: 'int32',
-  UInt32: 'uint32',
-  Int64: 'int64',
-  UInt64: 'uint64',
-
-  SizeValueType: 'uint64',
-  IdentifierType: 'uint64',
-  IndexValueType: 'int64',
-  OffsetValueType: 'int64'
-} as const
-
-export default IntTypes
diff --git a/src/core/interface-types/json-compatible.ts b/src/core/interface-types/json-compatible.ts
deleted file mode 100644
index c508022f1..000000000
--- a/src/core/interface-types/json-compatible.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-type JsonCompatible =
-    | null
-    | string
-    | number
-    | boolean
-    | { [key: string]: JsonCompatible }
-    | JsonCompatible[]
-
-export default JsonCompatible
diff --git a/src/core/interface-types/mesh-type.ts b/src/core/interface-types/mesh-type.ts
deleted file mode 100644
index 40e077c82..000000000
--- a/src/core/interface-types/mesh-type.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import IntTypes from './int-types.js'
-import FloatTypes from './float-types.js'
-import PixelTypes from './pixel-types.js'
-
-class MeshType {
-  constructor (
-    public readonly dimension: number = 2,
-    public readonly pointComponentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = FloatTypes.Float32,
-    public readonly pointPixelComponentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = FloatTypes.Float32,
-    public readonly pointPixelType: typeof PixelTypes[keyof typeof PixelTypes] = PixelTypes.Scalar,
-    public readonly pointPixelComponents: number = 1,
-    public readonly cellComponentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = IntTypes.Int32,
-    public readonly cellPixelComponentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = FloatTypes.Float32,
-    public readonly cellPixelType: typeof PixelTypes[keyof typeof PixelTypes] = PixelTypes.Scalar,
-    public readonly cellPixelComponents: number = 1) {}
-}
-
-export default MeshType
diff --git a/src/core/interface-types/mesh.ts b/src/core/interface-types/mesh.ts
deleted file mode 100644
index cb99e1720..000000000
--- a/src/core/interface-types/mesh.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import MeshType from './mesh-type.js'
-import type TypedArray from '../TypedArray.js'
-
-class Mesh {
-  meshType: MeshType
-
-  name: string = 'mesh'
-
-  numberOfPoints: number
-  points: null | TypedArray
-
-  numberOfPointPixels: number
-  pointData: null | TypedArray
-
-  numberOfCells: number
-  cells: null | TypedArray
-  cellBufferSize: number
-
-  numberOfCellPixels: number
-  cellData: null | TypedArray
-
-  constructor (public readonly mt = new MeshType()) {
-    this.meshType = mt
-
-    this.name = 'mesh'
-
-    this.numberOfPoints = 0
-    this.points = null
-
-    this.numberOfPointPixels = 0
-    this.pointData = null
-
-    this.numberOfCells = 0
-    this.cellBufferSize = 0
-    this.cells = null
-
-    this.numberOfCellPixels = 0
-    this.cellData = null
-  }
-}
-
-export default Mesh
diff --git a/src/core/interface-types/metadata.ts b/src/core/interface-types/metadata.ts
deleted file mode 100644
index 6685698ca..000000000
--- a/src/core/interface-types/metadata.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-type Metadata = Map<string, string | string[] | number | number[] | number[][]>
-
-export default Metadata
diff --git a/src/core/interface-types/pixel-types.ts b/src/core/interface-types/pixel-types.ts
deleted file mode 100644
index 533533b0d..000000000
--- a/src/core/interface-types/pixel-types.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-const PixelTypes = {
-  Unknown: 'Unknown',
-  Scalar: 'Scalar',
-  RGB: 'RGB',
-  RGBA: 'RGBA',
-  Offset: 'Offset',
-  Vector: 'Vector',
-  Point: 'Point',
-  CovariantVector: 'CovariantVector',
-  SymmetricSecondRankTensor: 'SymmetricSecondRankTensor',
-  DiffusionTensor3D: 'DiffusionTensor3D',
-  Complex: 'Complex',
-  FixedArray: 'FixedArray',
-  Array: 'Array',
-  Matrix: 'Matrix',
-  VariableLengthVector: 'VariableLengthVector',
-  VariableSizeMatrix: 'VariableSizeMatrix'
-} as const
-
-export default PixelTypes
diff --git a/src/core/interface-types/poly-data-type.ts b/src/core/interface-types/poly-data-type.ts
deleted file mode 100644
index f66de63b7..000000000
--- a/src/core/interface-types/poly-data-type.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import IntTypes from './int-types.js'
-import FloatTypes from './float-types.js'
-import PixelTypes from './pixel-types.js'
-
-class PolyDataType {
-  constructor (
-    public readonly pointPixelComponentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = FloatTypes.Float32,
-    public readonly pointPixelType: typeof PixelTypes[keyof typeof PixelTypes] = PixelTypes.Scalar,
-    public readonly pointPixelComponents: number = 1,
-    public readonly cellPixelComponentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] = FloatTypes.Float32,
-    public readonly cellPixelType: typeof PixelTypes[keyof typeof PixelTypes] = PixelTypes.Scalar,
-    public readonly cellPixelComponents: number = 1) {}
-}
-
-export default PolyDataType
diff --git a/src/core/interface-types/poly-data.ts b/src/core/interface-types/poly-data.ts
deleted file mode 100644
index af7a12925..000000000
--- a/src/core/interface-types/poly-data.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import PolyDataType from './poly-data-type.js'
-import TypedArray from '../TypedArray.js'
-
-class PolyData {
-  name: string = 'PolyData'
-
-  numberOfPoints: number
-  points: Float32Array
-
-  verticesBufferSize: number
-  vertices: null | Uint32Array
-
-  linesBufferSize: number
-  lines: null | Uint32Array
-
-  polygonsBufferSize: number
-  polygons: null | Uint32Array
-
-  triangleStripsBufferSize: number
-  triangleStrips: null | Uint32Array
-
-  numberOfPointPixels: number
-  pointData: null | TypedArray
-
-  numberOfCellPixels: number
-  cellData: null | TypedArray
-
-  constructor (public readonly polyDataType = new PolyDataType()) {
-    this.polyDataType = polyDataType
-
-    this.name = 'PolyData'
-
-    this.numberOfPoints = 0
-    this.points = new Float32Array()
-
-    this.verticesBufferSize = 0
-    this.vertices = null
-
-    this.linesBufferSize = 0
-    this.lines = null
-
-    this.polygonsBufferSize = 0
-    this.polygons = null
-
-    this.triangleStripsBufferSize = 0
-    this.triangleStrips = null
-
-    this.numberOfPointPixels = 0
-    this.pointData = null
-
-    this.numberOfCellPixels = 0
-    this.cellData = null
-  }
-}
-
-export default PolyData
diff --git a/src/core/interface-types/text-file.ts b/src/core/interface-types/text-file.ts
deleted file mode 100644
index 1d177b4d0..000000000
--- a/src/core/interface-types/text-file.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-interface TextFile {
-  data: string
-  path: string
-}
-
-export default TextFile
diff --git a/src/core/interface-types/text-stream.ts b/src/core/interface-types/text-stream.ts
deleted file mode 100644
index 3f25decb6..000000000
--- a/src/core/interface-types/text-stream.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-interface TextStream {
-  data: string
-}
-
-export default TextStream
diff --git a/src/core/internal/camelCase.ts b/src/core/internal/camelCase.ts
deleted file mode 100644
index e5407a3c7..000000000
--- a/src/core/internal/camelCase.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-function camelCase (kebobCase: string): string {
-  // make any alphabets that follows '-' an uppercase character, and remove the corresponding hyphen
-  const cameledParam = kebobCase.replace(/-([a-z])/g, (kk) => {
-    return kk[1].toUpperCase()
-  })
-
-  // remove all non-alphanumeric characters
-  const outParam = cameledParam.replace(/([^0-9a-z])/ig, '')
-
-  // check if resulting string is empty
-  if (outParam === '') {
-    console.error('Resulting string is empty.')
-  }
-  return outParam
-}
-
-export default camelCase
diff --git a/src/core/internal/imageTransferables.ts b/src/core/internal/imageTransferables.ts
deleted file mode 100644
index 6a66f4f8a..000000000
--- a/src/core/internal/imageTransferables.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import Image from '../interface-types/image.js'
-import TypedArray from '../TypedArray.js'
-
-function imageTransferables (image: Image): Array<TypedArray | null> {
-  return [
-    image.data,
-    image.direction
-  ]
-}
-
-export default imageTransferables
diff --git a/src/core/internal/loadEmscriptenModuleMainThread.ts b/src/core/internal/loadEmscriptenModuleMainThread.ts
deleted file mode 100644
index 863e77226..000000000
--- a/src/core/internal/loadEmscriptenModuleMainThread.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import axios from 'axios'
-
-import EmscriptenModule from '../ITKWasmEmscriptenModule.js'
-
-async function loadEmscriptenModuleMainThread (moduleRelativePathOrURL: string | URL, baseUrl: string): Promise<EmscriptenModule> {
-  let modulePrefix: string = 'unknown'
-  if (typeof moduleRelativePathOrURL !== 'string') {
-    modulePrefix = moduleRelativePathOrURL.href
-  } else if (moduleRelativePathOrURL.startsWith('http')) {
-    modulePrefix = moduleRelativePathOrURL
-  } else {
-    modulePrefix = `${baseUrl}/${moduleRelativePathOrURL}`
-  }
-  if (modulePrefix.endsWith('.js')) {
-    modulePrefix = modulePrefix.substring(0, modulePrefix.length - 3)
-  }
-  if (modulePrefix.endsWith('.wasm')) {
-    modulePrefix = modulePrefix.substring(0, modulePrefix.length - 5)
-  }
-  const wasmBinaryPath = `${modulePrefix}.wasm`
-  const response = await axios.get(wasmBinaryPath, { responseType: 'arraybuffer' })
-  const wasmBinary = response.data
-  const fullModulePath = `${modulePrefix}.js`
-  const result = await import(/* webpackIgnore: true */ /* @vite-ignore */ fullModulePath)
-  const instantiated = result.default({ wasmBinary }) as EmscriptenModule
-  return instantiated
-}
-
-export default loadEmscriptenModuleMainThread
diff --git a/src/core/internal/loadEmscriptenModuleNode.ts b/src/core/internal/loadEmscriptenModuleNode.ts
deleted file mode 100644
index b2de851aa..000000000
--- a/src/core/internal/loadEmscriptenModuleNode.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import fs from 'fs'
-import EmscriptenModule from '../ITKWasmEmscriptenModule.js'
-import { pathToFileURL } from 'url'
-
-async function loadEmscriptenModuleNode (modulePath: string): Promise<EmscriptenModule> {
-  let modulePrefix = modulePath
-  if (modulePath.endsWith('.js')) {
-    modulePrefix = modulePath.substring(0, modulePath.length - 3)
-  }
-  if (modulePath.endsWith('.wasm')) {
-    modulePrefix = modulePath.substring(0, modulePath.length - 5)
-  }
-  const wasmBinaryPath = `${modulePrefix}.wasm`
-  const wasmBinary = fs.readFileSync(wasmBinaryPath)
-  const fullModulePath = pathToFileURL(`${modulePrefix}.js`).href
-  const result = await import(/* webpackIgnore: true */ /* @vite-ignore */ fullModulePath)
-  const instantiated = result.default({ wasmBinary }) as EmscriptenModule
-  return instantiated
-}
-
-export default loadEmscriptenModuleNode
diff --git a/src/core/internal/loadEmscriptenModuleWebWorker.ts b/src/core/internal/loadEmscriptenModuleWebWorker.ts
deleted file mode 100644
index ca5ff89c2..000000000
--- a/src/core/internal/loadEmscriptenModuleWebWorker.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import axios from 'axios'
-
-import { ZSTDDecoder } from '@thewtex/zstddec'
-const decoder = new ZSTDDecoder()
-let decoderInitialized = false
-
-import ITKWasmEmscriptenModule from '../ITKWasmEmscriptenModule.js'
-
-// Load the Emscripten module in the browser in a WebWorker.
-//
-// baseUrl is usually taken from 'getPipelinesBaseUrl()', but a different value
-// could be passed.
-async function loadEmscriptenModuleWebWorker(moduleRelativePathOrURL: string | URL, baseUrl: string): Promise<ITKWasmEmscriptenModule> {
-  let modulePrefix = null
-  if (typeof moduleRelativePathOrURL !== 'string') {
-    modulePrefix = moduleRelativePathOrURL.href
-  } else if (moduleRelativePathOrURL.startsWith('http')) {
-    modulePrefix = moduleRelativePathOrURL
-  } else {
-    modulePrefix = `${baseUrl}/${moduleRelativePathOrURL}`
-  }
-  if (modulePrefix.endsWith('.js')) {
-    modulePrefix = modulePrefix.substring(0, modulePrefix.length - 3)
-  }
-  if (modulePrefix.endsWith('.wasm')) {
-    modulePrefix = modulePrefix.substring(0, modulePrefix.length - 5)
-  }
-  const wasmBinaryPath = `${modulePrefix}.wasm`
-  const response = await axios.get(`${wasmBinaryPath}.zst`, { responseType: 'arraybuffer' })
-  if (!decoderInitialized) {
-    await decoder.init()
-    decoderInitialized = true
-  }
-  const decompressedArray = decoder.decode(new Uint8Array(response.data))
-  const wasmBinary = decompressedArray.buffer
-  const modulePath = `${modulePrefix}.js`
-  const result = await import(/* webpackIgnore: true */ /* @vite-ignore */ modulePath)
-  const emscriptenModule = result.default({ wasmBinary }) as ITKWasmEmscriptenModule
-  return emscriptenModule
-}
-
-export default loadEmscriptenModuleWebWorker
diff --git a/src/core/internal/meshTransferables.ts b/src/core/internal/meshTransferables.ts
deleted file mode 100644
index b045c65e6..000000000
--- a/src/core/internal/meshTransferables.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import Mesh from '../interface-types/mesh.js'
-import TypedArray from '../TypedArray.js'
-
-function meshTransferables (mesh: Mesh): Array<TypedArray | null> {
-  return [
-    mesh.points,
-    mesh.pointData,
-    mesh.cells,
-    mesh.cellData
-  ]
-}
-
-export default meshTransferables
diff --git a/src/core/internal/polyDataTransferables.ts b/src/core/internal/polyDataTransferables.ts
deleted file mode 100644
index 6bea8eb12..000000000
--- a/src/core/internal/polyDataTransferables.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import PolyData from '../interface-types/poly-data.js'
-import TypedArray from '../TypedArray.js'
-
-function polyDataTransferables (polyData: PolyData): Array<ArrayBuffer | TypedArray | null> {
-  return [
-    polyData.points,
-    polyData.vertices,
-    polyData.lines,
-    polyData.polygons,
-    polyData.triangleStrips,
-    polyData.pointData,
-    polyData.cellData
-  ]
-}
-
-export default polyDataTransferables
diff --git a/src/core/pipeline-worker-url.ts b/src/core/pipeline-worker-url.ts
deleted file mode 100644
index dd8ff4f21..000000000
--- a/src/core/pipeline-worker-url.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-let pipelineWorkerUrl: string | URL | null | undefined
-
-export function setPipelineWorkerUrl (workerUrl: string | URL | null): void {
-  pipelineWorkerUrl = workerUrl
-}
-
-export function getPipelineWorkerUrl (): string | URL | null | undefined {
-  return pipelineWorkerUrl
-}
diff --git a/src/core/pipelines-base-url.ts b/src/core/pipelines-base-url.ts
deleted file mode 100644
index eb7a221a1..000000000
--- a/src/core/pipelines-base-url.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-let pipelinesBaseUrl: string | URL | undefined
-
-export function setPipelinesBaseUrl (baseUrl: string | URL): void {
-  pipelinesBaseUrl = baseUrl
-}
-
-export function getPipelinesBaseUrl (): string | URL | undefined {
-  return pipelinesBaseUrl
-}
diff --git a/src/core/setMatrixElement.ts b/src/core/setMatrixElement.ts
deleted file mode 100644
index fee1fcccb..000000000
--- a/src/core/setMatrixElement.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import TypedArray from './TypedArray.js'
-
-function setMatrixElement (matrixData: TypedArray, columns: number, row: number, column: number, value: number | bigint): void {
-  matrixData[column + row * columns] = value
-}
-
-export default setMatrixElement
diff --git a/src/core/stackImages.ts b/src/core/stackImages.ts
deleted file mode 100644
index 4d4c4e941..000000000
--- a/src/core/stackImages.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import Image from './interface-types/image.js'
-
-import TypedArray from './TypedArray.js'
-
-/** Join an array of sequential image slabs into a single image */
-function stackImages (images: Image[]): Image {
-  if (images.length < 1) {
-    throw Error('At least one images is required.')
-  }
-  const firstImage = images[0]
-  if (firstImage.data === null) {
-    throw Error('Image data is null.')
-  }
-  const result = new Image(firstImage.imageType)
-  result.origin = Array.from(firstImage.origin)
-  result.spacing = Array.from(firstImage.spacing)
-  const dimension = result.imageType.dimension
-  result.direction = firstImage.direction.slice()
-
-  const stackOn = dimension - 1
-
-  result.size = Array.from(firstImage.size)
-  const stackedSize = images.reduce((accumulator, currentValue) => {
-    return accumulator + currentValue.size[stackOn]
-  }, 0)
-  result.size[stackOn] = stackedSize
-
-  const dataSize = result.size.reduce((accumulator, currentValue) => { return accumulator * currentValue }, 1) * result.imageType.components
-  const CTor = firstImage.data.constructor as new(length: number) => typeof firstImage.data
-  result.data = new CTor(dataSize)
-
-  let offsetBase = result.imageType.components
-  for (let subIndex = 0; subIndex < result.size.length - 1; subIndex++) {
-    offsetBase *= result.size[subIndex]
-  }
-  let stackIndex = 0
-  if (result.data != null) {
-    for (let index = 0; index < images.length; index++) {
-      // @ts-expect-error: error TS2345: Argument of type 'TypedArray' is not assignable to parameter of type 'ArrayLike<number> & ArrayLike<bigint>'.
-      result.data.set(images[index].data as TypedArray, offsetBase * stackIndex)
-      stackIndex += images[index].size[stackOn]
-    }
-  } else {
-    throw Error('Could not create result image data.')
-  }
-
-  return result
-}
-
-export default stackImages
diff --git a/src/core/version.ts b/src/core/version.ts
deleted file mode 100644
index 6f8a22986..000000000
--- a/src/core/version.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-const version = '0.0.0-semantically-released'
-
-export default version
diff --git a/src/core/web-workers/io-input.ts b/src/core/web-workers/io-input.ts
deleted file mode 100644
index d2df44e0c..000000000
--- a/src/core/web-workers/io-input.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import RunPipelineInput from "./run-pipeline-input.js"
-
-interface IOInput extends RunPipelineInput {
-  fileName: string
-  mimeType: string
-}
-
-export default IOInput
diff --git a/src/core/web-workers/itk-config.ts b/src/core/web-workers/itk-config.ts
deleted file mode 100644
index df1653812..000000000
--- a/src/core/web-workers/itk-config.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-interface ITKConfig {
-  webWorkersUrl?: string
-  pipelineWorkerUrl?: string
-  pipelinesUrl: string
-  imageIOUrl: string
-  meshIOUrl: string
-
-  [key: string]: string | undefined
-}
-
-export default ITKConfig
diff --git a/src/core/web-workers/itk-wasm-pipeline.worker.ts b/src/core/web-workers/itk-wasm-pipeline.worker.ts
deleted file mode 100644
index dcfba349d..000000000
--- a/src/core/web-workers/itk-wasm-pipeline.worker.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as Comlink from 'comlink'
-
-import ITKConfig from './itk-config.js'
-import PipelineOutput from '../../pipeline/PipelineOutput.js'
-import PipelineInput from '../../pipeline/PipelineInput.js'
-import MeshToPolyDataPipelineResult from './mesh-to-poly-data-pipeline-result.js'
-import PolyDataToMeshPipelineResult from './poly-data-to-mesh-pipeline-result.js'
-import ReadImagePipelineResult from './read-image-pipeline-result.js'
-import WriteImagePipelineResult from './write-image-pipeline-result.js'
-import ReadMeshPipelineResult from './read-mesh-pipeline-result.js'
-import WriteMeshPipelineResult from './write-mesh-pipeline-result.js'
-import RunPipelineWorkerResult from './run-pipeline-worker-result.js'
-import loadPipelineModule from './load-pipeline-module.js'
-import loadImageIOPipelineModule from './load-image-io-pipeline-module.js'
-import loadMeshIOPipelineModule from './load-mesh-io-pipeline-module.js'
-import runPipeline from './run-pipeline.js'
-import RunPipelineInput from './run-pipeline-input.js'
-import IOInput from './io-input.js'
-
-const workerOperations = {
-  meshToPolyData: async function (config: ITKConfig, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]): Promise<MeshToPolyDataPipelineResult> {
-    const pipelineModule = await loadPipelineModule('mesh-to-polydata', config.meshIOUrl)
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-
-  polyDataToMesh: async function (config: ITKConfig, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]): Promise<PolyDataToMeshPipelineResult> {
-    const pipelineModule = await loadPipelineModule('polydata-to-mesh', config.meshIOUrl)
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-
-  readImage: async function (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]): Promise<ReadImagePipelineResult> {
-    const pipelineModule = await loadImageIOPipelineModule({ fileName, mimeType, config, args, outputs, inputs } as IOInput, '-read-image')
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-
-  writeImage: async function (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]): Promise<WriteImagePipelineResult> {
-    const pipelineModule = await loadImageIOPipelineModule({ fileName, mimeType, config, args, outputs, inputs } as IOInput, '-write-image')
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-
-  readMesh: async function (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]): Promise<ReadMeshPipelineResult> {
-    const pipelineModule = await loadMeshIOPipelineModule({ fileName, mimeType, config, args, outputs, inputs } as IOInput, '-read-mesh')
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-
-  writeMesh: async function (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]): Promise<WriteMeshPipelineResult> {
-    const pipelineModule = await loadMeshIOPipelineModule({ fileName, mimeType, config, args, outputs, inputs } as IOInput, '-write-mesh')
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-
-  runPipeline: async function (config: ITKConfig, pipelinePath: string, pipelineBaseUrl: string, args: string[], outputs: PipelineOutput[] | null, inputs: PipelineInput[] | null): Promise<RunPipelineWorkerResult> {
-    const resolvedPipelineBaseUrl = typeof config[pipelineBaseUrl] === 'undefined' ? pipelineBaseUrl : config[pipelineBaseUrl] as string
-    const pipelineModule = await loadPipelineModule(pipelinePath, resolvedPipelineBaseUrl)
-    return runPipeline(pipelineModule, args, outputs, inputs)
-  },
-}
-
-Comlink.expose(workerOperations)
\ No newline at end of file
diff --git a/src/core/web-workers/load-image-io-pipeline-module.ts b/src/core/web-workers/load-image-io-pipeline-module.ts
deleted file mode 100644
index ee7442d83..000000000
--- a/src/core/web-workers/load-image-io-pipeline-module.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import loadPipelineModule from './load-pipeline-module.js'
-import IOInput from './io-input.js'
-import PipelineEmscriptenModule from '../../pipeline/PipelineEmscriptenModule.js'
-import mimeToIO from '../../io/internal/MimeToImageIO.js'
-import extensionToIO from '../../io/extensionToImageIO.js'
-import getFileExtension from '../../io/getFileExtension.js'
-import ImageIOIndex from '../../io/internal/ImageIOIndex.js'
-import runPipelineEmscripten from '../../pipeline/internal/runPipelineEmscripten.js'
-
-async function * availableIOModules (input: IOInput) {
-  for (let idx = 0; idx < ImageIOIndex.length; idx++) {
-    const trialIO = ImageIOIndex[idx] + '-read-image'
-    const ioModule = await loadPipelineModule(trialIO, input.config.imageIOUrl) as PipelineEmscriptenModule
-    yield ioModule
-  }
-}
-
-async function loadImageIOPipelineModule(input: IOInput, postfix: string): Promise<PipelineEmscriptenModule> {
-  if (input.mimeType && mimeToIO.has(input.mimeType)) {
-    const io = mimeToIO.get(input.mimeType) + postfix
-    const ioModule = await loadPipelineModule(io, input.config.imageIOUrl)
-    return ioModule
-  }
-
-  const extension = getFileExtension(input.fileName)
-  if (extensionToIO.has(extension)) {
-    const io = extensionToIO.get(extension) + postfix
-    const ioModule = await loadPipelineModule(io, input.config.imageIOUrl)
-    return ioModule
-  }
-
-  for (let idx = 0; idx < ImageIOIndex.length; ++idx) {
-    let idx = 0
-    for await (const pipelineModule of availableIOModules(input)) {
-      try {
-        const { returnValue, outputs } = await runPipelineEmscripten(pipelineModule, input.args, input.outputs, input.inputs)
-        if (returnValue === 0) {
-          return pipelineModule
-        }
-      } catch (error) {
-        // continue
-      }
-      idx++
-    }
-  }
-
-  throw Error(`Could not find IO for: ${input.fileName}`)
-}
-
-export default loadImageIOPipelineModule
diff --git a/src/core/web-workers/load-mesh-io-pipeline-module.ts b/src/core/web-workers/load-mesh-io-pipeline-module.ts
deleted file mode 100644
index 1c78a5d51..000000000
--- a/src/core/web-workers/load-mesh-io-pipeline-module.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import loadPipelineModule from './load-pipeline-module.js'
-import IOInput from './io-input.js'
-import PipelineEmscriptenModule from '../../pipeline/PipelineEmscriptenModule.js'
-import mimeToIO from '../../io/internal/MimeToMeshIO.js'
-import extensionToIO from '../../io/extensionToMeshIO.js'
-import getFileExtension from '../../io/getFileExtension.js'
-import MeshIOIndex from '../../io/internal/MeshIOIndex.js'
-import runPipelineEmscripten from '../../pipeline/internal/runPipelineEmscripten.js'
-
-async function * availableIOModules (input: IOInput) {
-  for (let idx = 0; idx < MeshIOIndex.length; idx++) {
-    const trialIO = MeshIOIndex[idx] + '-read-mesh'
-    const ioModule = await loadPipelineModule(trialIO, input.config.meshIOUrl) as PipelineEmscriptenModule
-    yield ioModule
-  }
-}
-
-async function loadMeshIOPipelineModule(input: IOInput, postfix: string): Promise<PipelineEmscriptenModule> {
-  if (input.mimeType && mimeToIO.has(input.mimeType)) {
-    const io = mimeToIO.get(input.mimeType) + postfix
-    const ioModule = await loadPipelineModule(io, input.config.meshIOUrl)
-    return ioModule
-  }
-
-  const extension = getFileExtension(input.fileName)
-  if (extensionToIO.has(extension)) {
-    const io = extensionToIO.get(extension) + postfix
-    const ioModule = await loadPipelineModule(io, input.config.meshIOUrl)
-    return ioModule
-  }
-
-  for (let idx = 0; idx < MeshIOIndex.length; ++idx) {
-    let idx = 0
-    for await (const pipelineModule of availableIOModules(input)) {
-      try {
-        const { returnValue, outputs } = await runPipelineEmscripten(pipelineModule, input.args, input.outputs, input.inputs)
-        if (returnValue === 0) {
-          return pipelineModule
-        }
-      } catch (error) {
-        // continue
-      }
-      idx++
-    }
-  }
-
-  throw Error(`Could not find IO for: ${input.fileName}`)
-}
-
-export default loadMeshIOPipelineModule
diff --git a/src/core/web-workers/load-pipeline-module.ts b/src/core/web-workers/load-pipeline-module.ts
deleted file mode 100644
index 5286a0967..000000000
--- a/src/core/web-workers/load-pipeline-module.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import loadEmscriptenModule from '../internal/loadEmscriptenModuleWebWorker.js'
-import PipelineEmscriptenModule from '../../pipeline/PipelineEmscriptenModule.js'
-
-// To cache loaded pipeline modules
-const pipelineToModule: Map<string,PipelineEmscriptenModule> = new Map()
-
-async function loadPipelineModule (pipelinePath: string | object, baseUrl: string): Promise<PipelineEmscriptenModule> {
-  let moduleRelativePathOrURL: string | URL = pipelinePath as string
-  let pipeline = pipelinePath as string
-  let pipelineModule = null
-  if (typeof pipelinePath !== 'string') {
-    moduleRelativePathOrURL = new URL((pipelinePath as URL).href)
-    pipeline = moduleRelativePathOrURL.href
-  }
-  if (pipelineToModule.has(pipeline)) {
-    pipelineModule = pipelineToModule.get(pipeline) as PipelineEmscriptenModule
-  } else {
-    pipelineToModule.set(pipeline, await loadEmscriptenModule(moduleRelativePathOrURL, baseUrl) as PipelineEmscriptenModule)
-    pipelineModule = pipelineToModule.get(pipeline) as PipelineEmscriptenModule
-  }
-  return pipelineModule
-}
-
-export default loadPipelineModule
\ No newline at end of file
diff --git a/src/core/web-workers/mesh-to-poly-data-pipeline-result.ts b/src/core/web-workers/mesh-to-poly-data-pipeline-result.ts
deleted file mode 100644
index 613beff35..000000000
--- a/src/core/web-workers/mesh-to-poly-data-pipeline-result.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-  interface MeshToPolyDataPipelineResult {
-    outputs: any[]
-  }
-
-  export default MeshToPolyDataPipelineResult
\ No newline at end of file
diff --git a/src/core/web-workers/poly-data-to-mesh-pipeline-result.ts b/src/core/web-workers/poly-data-to-mesh-pipeline-result.ts
deleted file mode 100644
index 3b3d8a616..000000000
--- a/src/core/web-workers/poly-data-to-mesh-pipeline-result.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-  interface PolyDataToMeshPipelineResult {
-    outputs: any[]
-  }
-
-  export default PolyDataToMeshPipelineResult
\ No newline at end of file
diff --git a/src/core/web-workers/read-image-pipeline-result.ts b/src/core/web-workers/read-image-pipeline-result.ts
deleted file mode 100644
index 676ffccc0..000000000
--- a/src/core/web-workers/read-image-pipeline-result.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-interface ReadImagePipelineResult {
-    stdout: string
-    stderr: string
-    outputs: any[]
-}
-
-export default ReadImagePipelineResult
\ No newline at end of file
diff --git a/src/core/web-workers/read-mesh-pipeline-result.ts b/src/core/web-workers/read-mesh-pipeline-result.ts
deleted file mode 100644
index 285497e52..000000000
--- a/src/core/web-workers/read-mesh-pipeline-result.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-interface ReadMeshPipelineResult {
-    stdout: string
-    stderr: string
-    outputs: any[]
-}
-
-export default ReadMeshPipelineResult
\ No newline at end of file
diff --git a/src/core/web-workers/run-pipeline-input.ts b/src/core/web-workers/run-pipeline-input.ts
deleted file mode 100644
index 8bb56400b..000000000
--- a/src/core/web-workers/run-pipeline-input.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import PipelineInput from '../../pipeline/PipelineInput.js'
-import PipelineOutput from '../../pipeline/PipelineOutput.js'
-import WebWorkerInput from './web-worker-input.js'
-
-interface RunPipelineInput extends WebWorkerInput {
-  pipelinePath: string | object
-  pipelineBaseUrl: string,
-  args: string[]
-  outputs: PipelineOutput[]
-  inputs: PipelineInput[]
-}
-
-export default RunPipelineInput
\ No newline at end of file
diff --git a/src/core/web-workers/run-pipeline-worker-result.ts b/src/core/web-workers/run-pipeline-worker-result.ts
deleted file mode 100644
index b2375918b..000000000
--- a/src/core/web-workers/run-pipeline-worker-result.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-  import PipelineOutput from '../../pipeline/PipelineOutput.js'
-  interface RunPipelineWorkerResult {
-    returnValue: number
-    stdout: string
-    stderr: string
-    outputs: PipelineOutput[]
-  }
-
-  export default RunPipelineWorkerResult
\ No newline at end of file
diff --git a/src/core/web-workers/run-pipeline.ts b/src/core/web-workers/run-pipeline.ts
deleted file mode 100644
index 2f2912008..000000000
--- a/src/core/web-workers/run-pipeline.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-import * as Comlink from 'comlink'
-
-import PipelineEmscriptenModule from '../../pipeline/PipelineEmscriptenModule.js'
-import runPipelineEmscripten from '../../pipeline/internal/runPipelineEmscripten.js'
-import IOTypes from '../IOTypes.js'
-import getTransferables from '../get-transferables.js'
-
-import PipelineInput from '../../pipeline/PipelineInput.js'
-import PipelineOutput from '../../pipeline/PipelineOutput.js'
-
-import InterfaceTypes from '../InterfaceTypes.js'
-import Image from '../interface-types/image.js'
-import Mesh from '../interface-types/mesh.js'
-import PolyData from '../interface-types/poly-data.js'
-import TypedArray from '../TypedArray.js'
-import imageTransferables from '../internal/imageTransferables.js'
-import meshTransferables from '../internal/meshTransferables.js'
-import polyDataTransferables from '../internal/polyDataTransferables.js'
-
-async function runPipeline(pipelineModule: PipelineEmscriptenModule, args: string[], outputs: PipelineOutput[] | null, inputs: PipelineInput[] | null) {
-  const result = runPipelineEmscripten(pipelineModule, args, outputs, inputs)
-
-  const transferables: (ArrayBuffer | TypedArray | null)[] = []
-  if (result.outputs) {
-    result.outputs.forEach(function (output) {
-      if (output.type === InterfaceTypes.BinaryStream || output.type === InterfaceTypes.BinaryFile) {
-        // Binary data
-        const binary = output.data as Uint8Array
-        transferables.push(binary)
-      } else if (output.type === InterfaceTypes.Image) {
-        // Image data
-        const image = output.data as Image
-        transferables.push(...imageTransferables(image))
-      } else if (output.type === InterfaceTypes.Mesh) {
-        const mesh = output.data as Mesh
-        transferables.push(...meshTransferables(mesh))
-      } else if (output.type === InterfaceTypes.PolyData) {
-        const polyData = output.data as PolyData
-        transferables.push(...polyDataTransferables(polyData))
-      } else if (output.type === IOTypes.Binary) {
-        // Binary data
-        const binary = output.data as Uint8Array
-        transferables.push(binary)
-      } else if (output.type === IOTypes.Image) {
-        // Image data
-        const image = output.data as Image
-        transferables.push(...imageTransferables(image))
-      } else if (output.type === IOTypes.Mesh) {
-        // Mesh data
-        const mesh = output.data as Mesh
-        transferables.push(...meshTransferables(mesh))
-      }
-    })
-  }
-
-  return Comlink.transfer(result, getTransferables(transferables))
-}
-
-export default runPipeline
diff --git a/src/core/web-workers/web-worker-input.ts b/src/core/web-workers/web-worker-input.ts
deleted file mode 100644
index 60e38f6cc..000000000
--- a/src/core/web-workers/web-worker-input.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import ITKConfig from './itk-config.js'
-
-interface WebWorkerInput {
-  operation: 'runPipeline' | 'runPolyDataIOPipeline' | 'readImage' | 'writeImage' | 'readMesh' | 'writeMesh' | 'meshToPolyData' |  'polyDataToMesh'
-  config: ITKConfig
-}
-
-export default WebWorkerInput
diff --git a/src/core/web-workers/worker-operations.ts b/src/core/web-workers/worker-operations.ts
deleted file mode 100644
index 73a91752d..000000000
--- a/src/core/web-workers/worker-operations.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import ITKConfig from './itk-config.js'
-import PipelineOutput from '../../pipeline/PipelineOutput.js'
-import PipelineInput from '../../pipeline/PipelineInput.js'
-import MeshToPolyDataPipelineResult from './mesh-to-poly-data-pipeline-result.js'
-import PolyDataToMeshPipelineResult from './poly-data-to-mesh-pipeline-result.js'
-import ReadImagePipelineResult from './read-image-pipeline-result.js'
-import WriteImagePipelineResult from './write-image-pipeline-result.js'
-import ReadMeshPipelineResult from './read-mesh-pipeline-result.js'
-import WriteMeshPipelineResult from './write-mesh-pipeline-result.js'
-import RunPipelineWorkerResult from './run-pipeline-worker-result.js'
-
-interface WorkerOperations {
-  meshToPolyData: (config: ITKConfig, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]) => MeshToPolyDataPipelineResult
-  polyDataToMesh: (config: ITKConfig, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]) => PolyDataToMeshPipelineResult
-  readImage: (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]) => ReadImagePipelineResult
-  writeImage: (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]) => WriteImagePipelineResult
-  readMesh: (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]) => ReadMeshPipelineResult
-  writeMesh: (config: ITKConfig, mimeType: string, fileName: string, args: string[], outputs: PipelineOutput[], inputs: PipelineInput[]) => WriteMeshPipelineResult
-  runPipeline: (config: ITKConfig, pipelinePath: string, pipelineBaseUrl: string, args: string[], outputs: PipelineOutput[] | null, inputs: PipelineInput[] | null) => RunPipelineWorkerResult
-}
-
-export default WorkerOperations
\ No newline at end of file
diff --git a/src/core/web-workers/worker-proxy.ts b/src/core/web-workers/worker-proxy.ts
deleted file mode 100644
index 0e3d4ca86..000000000
--- a/src/core/web-workers/worker-proxy.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import * as Comlink from 'comlink'
-
-import WorkerOperations from './worker-operations.js'
-
-type WorkerProxy = Comlink.Remote<WorkerOperations>
-
-export default WorkerProxy
\ No newline at end of file
diff --git a/src/core/web-workers/write-image-pipeline-result.ts b/src/core/web-workers/write-image-pipeline-result.ts
deleted file mode 100644
index 2f62fb3a0..000000000
--- a/src/core/web-workers/write-image-pipeline-result.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-interface WriteImagePipelineResult {
-    stdout: string
-    stderr: string
-    outputs: any[]
-}
-
-export default WriteImagePipelineResult
\ No newline at end of file
diff --git a/src/core/web-workers/write-mesh-pipeline-result.ts b/src/core/web-workers/write-mesh-pipeline-result.ts
deleted file mode 100644
index be30423cb..000000000
--- a/src/core/web-workers/write-mesh-pipeline-result.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-interface WriteMeshPipelineResult {
-    stdout: string
-    stderr: string
-    outputs: any[]
-}
-
-export default WriteMeshPipelineResult
\ No newline at end of file
diff --git a/src/index.ts b/src/index.ts
deleted file mode 100644
index 0a955120a..000000000
--- a/src/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// itk-wasm API interfaces, data structures, and functions
-
-export * from './core/index.js'
-
-export * from './core/pipeline-worker-url.js'
-export * from './core/pipelines-base-url.js'
-
-export { default as ReadImageResult } from './io/ReadImageResult.js'
-export { default as ReadMeshResult } from './io/ReadMeshResult.js'
-
-export { default as ReadDICOMTagsResult } from './io/deprecated/ReadDICOMTagsResult.js'
-
-export { default as WriteArrayBufferResult } from './io/WriteArrayBufferResult.js'
-export { default as WriteMeshOptions } from './io/WriteMeshOptions.js'
-
-export * from './io/browser/index.js'
-export * from './io/node/index.js'
-
-export { default as PipelineInput } from './pipeline/PipelineInput.js'
-export { default as PipelineOutput } from './pipeline/PipelineOutput.js'
-export { default as RunPipelineResult } from './pipeline/RunPipelineResult.js'
-
-export * from './pipeline/browser/index.js'
-export * from './pipeline/node/index.js'
diff --git a/src/io/browser/index.ts b/src/io/browser/index.ts
deleted file mode 100644
index 1703d5811..000000000
--- a/src/io/browser/index.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-// Browser IO functions
-
-export { default as getFileExtension } from './../getFileExtension.js'
-export { default as extensionToImageIO } from './../extensionToImageIO.js'
-export { default as extensionToMeshIO } from './../extensionToMeshIO.js'
-
-export { default as ReadImageArrayBufferOptions } from './../ReadImageArrayBufferOptions.js'
-export { default as readImageArrayBuffer } from './../readImageArrayBuffer.js'
-export { default as readMeshArrayBuffer } from './../readMeshArrayBuffer.js'
-export { default as readArrayBuffer } from './../readArrayBuffer.js'
-
-export { default as readImageBlob } from './../readImageBlob.js'
-export { default as readMeshBlob } from './../readMeshBlob.js'
-export { default as readBlob } from './../readBlob.js'
-
-export { default as readImageFile } from './../readImageFile.js'
-export { default as readMeshFile } from './../readMeshFile.js'
-export { default as ReadImageFileSeriesOptions } from './../ReadImageFileSeriesOptions.js'
-export { default as readImageFileSeries } from './../readImageFileSeries.js'
-export { default as ReadImageFileSeriesResult } from './../ReadImageFileSeriesResult.js'
-export { default as readFile } from './../readFile.js'
-
-export { default as readImageHTTP } from './../readImageHTTP.js'
-
-export { default as readDICOMTags } from './../deprecated/readDICOMTags.js'
-export { default as readDICOMTagsArrayBuffer } from './../deprecated/readDICOMTagsArrayBuffer.js'
-export { default as ReadImageDICOMFileSeriesOptions } from './../deprecated/ReadImageDICOMFileSeriesOptions.js'
-export { default as readImageDICOMFileSeries } from './../deprecated/readImageDICOMFileSeries.js'
-export { default as ReadImageDICOMArrayBufferSeriesOptions } from './../deprecated/ReadImageDICOMArrayBufferSeriesOptions.js'
-export { default as readImageDICOMArrayBufferSeries } from './../deprecated/readImageDICOMArrayBufferSeries.js'
-
-export { default as WriteImageOptions } from './../WriteImageOptions.js'
-export { default as writeImageArrayBuffer } from './../writeImageArrayBuffer.js'
-export { default as WriteMeshOptions } from './../WriteMeshOptions.js'
-export { default as writeMeshArrayBuffer } from './../writeMeshArrayBuffer.js'
-export { default as writeArrayBuffer } from './../writeArrayBuffer.js'
-
-export { default as meshToPolyData } from './../meshToPolyData.js'
-export { default as polyDataToMesh } from './../polyDataToMesh.js'
diff --git a/src/io/extensionToImageIO.ts b/src/io/extensionToImageIO.ts
deleted file mode 100644
index 0b6de07b5..000000000
--- a/src/io/extensionToImageIO.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-const extensionToIO = new Map([
-  ['bmp', 'BMPImageIO'],
-  ['BMP', 'BMPImageIO'],
-
-  ['dcm', 'GDCMImageIO'],
-  ['DCM', 'GDCMImageIO'],
-
-  ['gipl', 'GiplImageIO'],
-  ['gipl.gz', 'GiplImageIO'],
-
-  ['hdf5', 'HDF5ImageIO'],
-
-  ['jpg', 'JPEGImageIO'],
-  ['JPG', 'JPEGImageIO'],
-  ['jpeg', 'JPEGImageIO'],
-  ['JPEG', 'JPEGImageIO'],
-
-  ['iwi', 'WasmImageIO'],
-  ['iwi.cbor', 'WasmImageIO'],
-  ['iwi.cbor.zst', 'WasmZstdImageIO'],
-
-  ['lsm', 'LSMImageIO'],
-
-  ['mnc', 'MINCImageIO'],
-  ['MNC', 'MINCImageIO'],
-  ['mnc.gz', 'MINCImageIO'],
-  ['MNC.GZ', 'MINCImageIO'],
-  ['mnc2', 'MINCImageIO'],
-  ['MNC2', 'MINCImageIO'],
-
-  ['mgh', 'MGHImageIO'],
-  ['mgz', 'MGHImageIO'],
-  ['mgh.gz', 'MGHImageIO'],
-
-  ['mha', 'MetaImageIO'],
-  ['mhd', 'MetaImageIO'],
-
-  ['mrc', 'MRCImageIO'],
-
-  ['nia', 'NiftiImageIO'],
-  ['nii', 'NiftiImageIO'],
-  ['nii.gz', 'NiftiImageIO'],
-  ['hdr', 'NiftiImageIO'],
-
-  ['nrrd', 'NrrdImageIO'],
-  ['NRRD', 'NrrdImageIO'],
-  ['nhdr', 'NrrdImageIO'],
-  ['NHDR', 'NrrdImageIO'],
-
-  ['png', 'PNGImageIO'],
-  ['PNG', 'PNGImageIO'],
-
-  ['pic', 'BioRadImageIO'],
-  ['PIC', 'BioRadImageIO'],
-
-  ['tif', 'TIFFImageIO'],
-  ['TIF', 'TIFFImageIO'],
-  ['tiff', 'TIFFImageIO'],
-  ['TIFF', 'TIFFImageIO'],
-
-  ['vtk', 'VTKImageIO'],
-  ['VTK', 'VTKImageIO'],
-
-  ['isq', 'ScancoImageIO'],
-  ['ISQ', 'ScancoImageIO'],
-
-  ['fdf', 'FDFImageIO'],
-  ['FDF', 'FDFImageIO']
-])
-
-export default extensionToIO
diff --git a/src/io/extensionToMeshIO.ts b/src/io/extensionToMeshIO.ts
deleted file mode 100644
index b65f0e179..000000000
--- a/src/io/extensionToMeshIO.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-const extensionToIO = new Map([
-  ['vtk', 'VTKPolyDataMeshIO'],
-  ['VTK', 'VTKPolyDataMeshIO'],
-  ['byu', 'BYUMeshIO'],
-  ['BYU', 'BYUMeshIO'],
-  ['fsa', 'FreeSurferAsciiMeshIO'],
-  ['FSA', 'FreeSurferAsciiMeshIO'],
-  ['fsb', 'FreeSurferBinaryMeshIO'],
-  ['FSB', 'FreeSurferBinaryMeshIO'],
-  ['obj', 'OBJMeshIO'],
-  ['OBJ', 'OBJMeshIO'],
-  ['off', 'OFFMeshIO'],
-  ['OFF', 'OFFMeshIO'],
-  ['stl', 'STLMeshIO'],
-  ['STL', 'STLMeshIO'],
-  ['swc', 'SWCMeshIO'],
-  ['SWC', 'SWCMeshIO'],
-  ['iwm', 'WasmMeshIO'],
-  ['iwm.cbor', 'WasmMeshIO'],
-  ['iwm.cbor.zst', 'WasmZstdMeshIO']
-])
-
-export default extensionToIO
diff --git a/src/io/getFileExtension.ts b/src/io/getFileExtension.ts
deleted file mode 100644
index 48fe9c081..000000000
--- a/src/io/getFileExtension.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-function getFileExtension (filePath: string): string {
-  let extension = filePath.slice((filePath.lastIndexOf('.') - 1 >>> 0) + 2)
-  if (extension.toLowerCase() === 'gz') {
-    const index = filePath.slice(0, -3).lastIndexOf('.')
-    extension = filePath.slice((index - 1 >>> 0) + 2)
-  } else if (extension.toLowerCase() === 'cbor') {
-    const index = filePath.slice(0, -5).lastIndexOf('.')
-    extension = filePath.slice((index - 1 >>> 0) + 2)
-  } else if (extension.toLowerCase() === 'zst') {
-    // .iwi.cbor.zstd
-    const index = filePath.slice(0, -10).lastIndexOf('.')
-    extension = filePath.slice((index - 1 >>> 0) + 2)
-  } else if (extension.toLowerCase() === 'zip') {
-    const index = filePath.slice(0, -4).lastIndexOf('.')
-    extension = filePath.slice((index - 1 >>> 0) + 2)
-  }
-  return extension
-}
-
-export default getFileExtension
diff --git a/src/io/internal/ByteOrder.ts b/src/io/internal/ByteOrder.ts
deleted file mode 100644
index 96256149a..000000000
--- a/src/io/internal/ByteOrder.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-const ByteOrder = {
-  BigEndian: 0,
-  LittleEndian: 1,
-  OrderNotApplicable: 2
-} as const
-
-export default ByteOrder
diff --git a/src/io/internal/FileType.ts b/src/io/internal/FileType.ts
deleted file mode 100644
index 4719d5bf9..000000000
--- a/src/io/internal/FileType.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-const FileType = {
-  ASCII: 0,
-  BINARY: 1,
-  TYPENOTAPPLICABLE: 2
-} as const
-
-export default FileType
diff --git a/src/io/internal/IOComponent.ts b/src/io/internal/IOComponent.ts
deleted file mode 100644
index 8d5748c02..000000000
--- a/src/io/internal/IOComponent.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-const IOComponent = {
-  UNKNOWNCOMPONENTTYPE: 0,
-  UCHAR: 1,
-  CHAR: 2,
-  USHORT: 3,
-  SHORT: 4,
-  UINT: 5,
-  INT: 6,
-  ULONG: 7,
-  LONG: 8,
-  LONGLONG: 9,
-  ULONGLONG: 10,
-  FLOAT: 11,
-  DOUBLE: 12,
-  LDOUBLE: 13
-} as const
-
-export default IOComponent
diff --git a/src/io/internal/IOEmscriptenModule.ts b/src/io/internal/IOEmscriptenModule.ts
deleted file mode 100644
index ae935ef13..000000000
--- a/src/io/internal/IOEmscriptenModule.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import IOComponent from './IOComponent.js'
-import IOPixel from './IOPixel.js'
-
-interface IOEmscriptenModule {
-  IOComponentType: typeof IOComponent
-  IOPixelType: typeof IOPixel
-}
-
-export default IOEmscriptenModule
diff --git a/src/io/internal/IOPixel.ts b/src/io/internal/IOPixel.ts
deleted file mode 100644
index 6e52ea763..000000000
--- a/src/io/internal/IOPixel.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-const IOPixel = {
-  UNKNOWNPIXELTYPE: 0,
-  SCALAR: 1,
-  RGB: 2,
-  RGBA: 3,
-  OFFSET: 4,
-  VECTOR: 5,
-  POINT: 6,
-  COVARIANTVECTOR: 7,
-  SYMMETRICSECONDRANKTENSOR: 8,
-  DIFFUSIONTENSOR3D: 9,
-  COMPLEX: 10,
-  FIXEDARRAY: 11,
-  ARRAY: 12,
-  MATRIX: 13,
-  VARIABLELENGTHVECTOR: 14,
-  VARIABLESIZEMATRIX: 15
-} as const
-
-export default IOPixel
diff --git a/src/io/internal/ImageIOIndex.ts.in b/src/io/internal/ImageIOIndex.ts.in
deleted file mode 100644
index f7daad830..000000000
--- a/src/io/internal/ImageIOIndex.ts.in
+++ /dev/null
@@ -1,3 +0,0 @@
-const ImageIOIndex = [@ImageIOIndex_ARRAY@]
-
-export default ImageIOIndex
diff --git a/src/io/internal/MeshIOIndex.ts.in b/src/io/internal/MeshIOIndex.ts.in
deleted file mode 100644
index 4372cc1ce..000000000
--- a/src/io/internal/MeshIOIndex.ts.in
+++ /dev/null
@@ -1,3 +0,0 @@
-const MeshIOIndex = [@MeshIOIndex_ARRAY@]
-
-export default MeshIOIndex
diff --git a/src/io/internal/MimeToImageIO.ts b/src/io/internal/MimeToImageIO.ts
deleted file mode 100644
index 084ad0eb2..000000000
--- a/src/io/internal/MimeToImageIO.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-const mimeToIO = new Map([
-  ['image/jpeg', 'JPEGImageIO'],
-  ['image/png', 'PNGImageIO'],
-  ['image/tiff', 'TIFFImageIO'],
-  ['image/x-ms-bmp', 'BMPImageIO'],
-  ['image/x-bmp', 'BMPImageIO'],
-  ['image/bmp', 'BMPImageIO'],
-  ['application/dicom', 'GDCMImageIO']
-])
-
-export default mimeToIO
diff --git a/src/io/internal/MimeToMeshIO.ts b/src/io/internal/MimeToMeshIO.ts
deleted file mode 100644
index 2c6c962b5..000000000
--- a/src/io/internal/MimeToMeshIO.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-const mimeToIO = new Map([
-])
-
-export default mimeToIO
diff --git a/src/io/internal/findLocalImageIOPath.ts b/src/io/internal/findLocalImageIOPath.ts
deleted file mode 100644
index fd92c83c6..000000000
--- a/src/io/internal/findLocalImageIOPath.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import fs from 'fs'
-
-import localPathRelativeToModule from './localPathRelativeToModule.js'
-
-function findLocalImageIOPath (): string {
-  const buildPath = localPathRelativeToModule(import.meta.url, '../../image-io')
-  if (fs.existsSync(buildPath)) {
-    return buildPath
-  }
-  const packagePath = localPathRelativeToModule(import.meta.url, '../../../../itk-image-io')
-  if (fs.existsSync(packagePath)) {
-    return packagePath
-  }
-  throw Error("Cannot find path to itk image IO's. Try: npm install --save itk-image-io")
-}
-
-export default findLocalImageIOPath
diff --git a/src/io/internal/findLocalMeshIOPath.ts b/src/io/internal/findLocalMeshIOPath.ts
deleted file mode 100644
index b0e0f7251..000000000
--- a/src/io/internal/findLocalMeshIOPath.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import fs from 'fs'
-
-import localPathRelativeToModule from './localPathRelativeToModule.js'
-
-function findLocalMeshIOPath (): string {
-  const buildPath = localPathRelativeToModule(import.meta.url, '../../mesh-io')
-  if (fs.existsSync(buildPath)) {
-    return buildPath
-  }
-  const packagePath = localPathRelativeToModule(import.meta.url, '../../../../itk-mesh-io')
-  if (fs.existsSync(packagePath)) {
-    return packagePath
-  }
-  throw Error("Cannot find path to itk mesh IO's. Try: npm install --save itk-mesh-io")
-}
-
-export default findLocalMeshIOPath
diff --git a/src/io/internal/imageIOComponentToJSComponent.ts b/src/io/internal/imageIOComponentToJSComponent.ts
deleted file mode 100644
index 134c06d53..000000000
--- a/src/io/internal/imageIOComponentToJSComponent.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import IntTypes from '../../core/interface-types/int-types.js'
-import FloatTypes from '../../core/interface-types/float-types.js'
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-import IOComponent from './IOComponent.js'
-
-function imageIOComponentToJSComponent (emscriptenModule: IOEmscriptenModule,
-  ioComponentType: typeof IOComponent[keyof typeof IOComponent]):
-  typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] | null {
-  let componentType = null
-  switch (ioComponentType) {
-    case emscriptenModule.IOComponentType.UCHAR: {
-      componentType = IntTypes.UInt8
-      break
-    }
-    case emscriptenModule.IOComponentType.CHAR: {
-      componentType = IntTypes.Int8
-      break
-    }
-    case emscriptenModule.IOComponentType.USHORT: {
-      componentType = IntTypes.UInt16
-      break
-    }
-    case emscriptenModule.IOComponentType.SHORT: {
-      componentType = IntTypes.Int16
-      break
-    }
-    case emscriptenModule.IOComponentType.UINT: {
-      componentType = IntTypes.UInt32
-      break
-    }
-    case emscriptenModule.IOComponentType.INT: {
-      componentType = IntTypes.Int32
-      break
-    }
-    case emscriptenModule.IOComponentType.ULONG: {
-      componentType = IntTypes.UInt64
-      break
-    }
-    case emscriptenModule.IOComponentType.LONG: {
-      componentType = IntTypes.Int64
-      break
-    }
-    case emscriptenModule.IOComponentType.ULONGLONG: {
-      componentType = IntTypes.UInt64
-      break
-    }
-    case emscriptenModule.IOComponentType.LONGLONG: {
-      componentType = IntTypes.Int64
-      break
-    }
-    case emscriptenModule.IOComponentType.FLOAT: {
-      componentType = FloatTypes.Float32
-      break
-    }
-    case emscriptenModule.IOComponentType.DOUBLE: {
-      componentType = FloatTypes.Float64
-      break
-    }
-    default:
-      throw new Error('Unknown IO component type')
-  }
-
-  return componentType
-}
-
-export default imageIOComponentToJSComponent
diff --git a/src/io/internal/imageIOPixelTypeToJSPixelType.ts b/src/io/internal/imageIOPixelTypeToJSPixelType.ts
deleted file mode 100644
index 3ee74f3d0..000000000
--- a/src/io/internal/imageIOPixelTypeToJSPixelType.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import PixelTypes from '../../core/interface-types/pixel-types.js'
-import IOPixel from './IOPixel.js'
-
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-
-function imageIOPixelTypeToJSPixelType (emscriptenModule: IOEmscriptenModule, ioPixelType: typeof IOPixel[keyof typeof IOPixel]): typeof PixelTypes[keyof typeof PixelTypes] {
-  let pixelType = null
-  switch (ioPixelType) {
-    case emscriptenModule.IOPixelType.UNKNOWNPIXELTYPE: {
-      pixelType = PixelTypes.Unknown
-      break
-    }
-    case emscriptenModule.IOPixelType.SCALAR: {
-      pixelType = PixelTypes.Scalar
-      break
-    }
-    case emscriptenModule.IOPixelType.RGB: {
-      pixelType = PixelTypes.RGB
-      break
-    }
-    case emscriptenModule.IOPixelType.RGBA: {
-      pixelType = PixelTypes.RGBA
-      break
-    }
-    case emscriptenModule.IOPixelType.OFFSET: {
-      pixelType = PixelTypes.Offset
-      break
-    }
-    case emscriptenModule.IOPixelType.VECTOR: {
-      pixelType = PixelTypes.Vector
-      break
-    }
-    case emscriptenModule.IOPixelType.POINT: {
-      pixelType = PixelTypes.Point
-      break
-    }
-    case emscriptenModule.IOPixelType.COVARIANTVECTOR: {
-      pixelType = PixelTypes.CovariantVector
-      break
-    }
-    case emscriptenModule.IOPixelType.SYMMETRICSECONDRANKTENSOR: {
-      pixelType = PixelTypes.SymmetricSecondRankTensor
-      break
-    }
-    case emscriptenModule.IOPixelType.DIFFUSIONTENSOR3D: {
-      pixelType = PixelTypes.DiffusionTensor3D
-      break
-    }
-    case emscriptenModule.IOPixelType.COMPLEX: {
-      pixelType = PixelTypes.Complex
-      break
-    }
-    case emscriptenModule.IOPixelType.FIXEDARRAY: {
-      pixelType = PixelTypes.FixedArray
-      break
-    }
-    case emscriptenModule.IOPixelType.MATRIX: {
-      pixelType = PixelTypes.Matrix
-      break
-    }
-    default:
-      throw new Error('Unknown IO pixel type')
-  }
-  return pixelType
-}
-
-export default imageIOPixelTypeToJSPixelType
diff --git a/src/io/internal/imageJSComponentToIOComponent.ts b/src/io/internal/imageJSComponentToIOComponent.ts
deleted file mode 100644
index ea8502429..000000000
--- a/src/io/internal/imageJSComponentToIOComponent.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-import IntTypes from '../../core/interface-types/int-types.js'
-import FloatTypes from '../../core/interface-types/float-types.js'
-
-import IOComponent from './IOComponent.js'
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-
-function imageJSComponentToIOComponent (emscriptenModule: IOEmscriptenModule,
-  componentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] | null): typeof IOComponent[keyof typeof IOComponent] | null {
-  let ioComponentType = null
-  switch (componentType) {
-    case IntTypes.UInt8: {
-      ioComponentType = emscriptenModule.IOComponentType.UCHAR
-      break
-    }
-    case IntTypes.Int8: {
-      ioComponentType = emscriptenModule.IOComponentType.CHAR
-      break
-    }
-    case IntTypes.UInt16: {
-      ioComponentType = emscriptenModule.IOComponentType.USHORT
-      break
-    }
-    case IntTypes.Int16: {
-      ioComponentType = emscriptenModule.IOComponentType.SHORT
-      break
-    }
-    case IntTypes.UInt32: {
-      ioComponentType = emscriptenModule.IOComponentType.UINT
-      break
-    }
-    case IntTypes.Int32: {
-      ioComponentType = emscriptenModule.IOComponentType.INT
-      break
-    }
-    case IntTypes.UInt64: {
-      ioComponentType = emscriptenModule.IOComponentType.ULONGLONG
-      break
-    }
-    case IntTypes.Int64: {
-      ioComponentType = emscriptenModule.IOComponentType.LONGLONG
-      break
-    }
-    case FloatTypes.Float32: {
-      ioComponentType = emscriptenModule.IOComponentType.FLOAT
-      break
-    }
-    case FloatTypes.Float64: {
-      ioComponentType = emscriptenModule.IOComponentType.DOUBLE
-      break
-    }
-    default:
-      throw new Error('Unknown IO component type')
-  }
-
-  return ioComponentType
-}
-
-export default imageJSComponentToIOComponent
diff --git a/src/io/internal/imageJSPixelTypeToIOPixelType.ts b/src/io/internal/imageJSPixelTypeToIOPixelType.ts
deleted file mode 100644
index cd4d7ebc2..000000000
--- a/src/io/internal/imageJSPixelTypeToIOPixelType.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import PixelTypes from '../../core/interface-types/pixel-types.js'
-
-import IOPixel from './IOPixel.js'
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-
-function imageJSPixelTypeToIOPixelType (emscriptenModule: IOEmscriptenModule,
-  pixelType: typeof PixelTypes[keyof typeof PixelTypes]): typeof IOPixel[keyof typeof IOPixel] {
-  let ioPixelType = null
-  switch (pixelType) {
-    case PixelTypes.Unknown: {
-      ioPixelType = emscriptenModule.IOPixelType.UNKNOWNPIXELTYPE
-      break
-    }
-    case PixelTypes.Scalar: {
-      ioPixelType = emscriptenModule.IOPixelType.SCALAR
-      break
-    }
-    case PixelTypes.RGB: {
-      ioPixelType = emscriptenModule.IOPixelType.RGB
-      break
-    }
-    case PixelTypes.RGBA: {
-      ioPixelType = emscriptenModule.IOPixelType.RGBA
-      break
-    }
-    case PixelTypes.Offset: {
-      ioPixelType = emscriptenModule.IOPixelType.OFFSET
-      break
-    }
-    case PixelTypes.Vector: {
-      ioPixelType = emscriptenModule.IOPixelType.VECTOR
-      break
-    }
-    case PixelTypes.Point: {
-      ioPixelType = emscriptenModule.IOPixelType.POINT
-      break
-    }
-    case PixelTypes.CovariantVector: {
-      ioPixelType = emscriptenModule.IOPixelType.COVARIANTVECTOR
-      break
-    }
-    case PixelTypes.SymmetricSecondRankTensor: {
-      ioPixelType = emscriptenModule.IOPixelType.SYMMETRICSECONDRANKTENSOR
-      break
-    }
-    case PixelTypes.DiffusionTensor3D: {
-      ioPixelType = emscriptenModule.IOPixelType.DIFFUSIONTENSOR3D
-      break
-    }
-    case PixelTypes.Complex: {
-      ioPixelType = emscriptenModule.IOPixelType.COMPLEX
-      break
-    }
-    case PixelTypes.FixedArray: {
-      ioPixelType = emscriptenModule.IOPixelType.FIXEDARRAY
-      break
-    }
-    case PixelTypes.Matrix: {
-      ioPixelType = emscriptenModule.IOPixelType.MATRIX
-      break
-    }
-    default:
-      throw new Error('Unknown IO pixel type')
-  }
-  return ioPixelType
-}
-
-export default imageJSPixelTypeToIOPixelType
diff --git a/src/io/internal/localPathRelativeToModule.ts b/src/io/internal/localPathRelativeToModule.ts
deleted file mode 100644
index 44f2546b8..000000000
--- a/src/io/internal/localPathRelativeToModule.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { resolve, dirname } from 'path'
-import { fileURLToPath } from 'url'
-
-function localPathRelativeToModule (moduleUrl: string, relativePath: string): string {
-  const modulePath = fileURLToPath(moduleUrl)
-  return resolve(dirname(modulePath), relativePath)
-}
-
-export default localPathRelativeToModule
diff --git a/src/io/internal/meshIOComponentToJSComponent.ts b/src/io/internal/meshIOComponentToJSComponent.ts
deleted file mode 100644
index 7bf636c0e..000000000
--- a/src/io/internal/meshIOComponentToJSComponent.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import IntTypes from '../../core/interface-types/int-types.js'
-import FloatTypes from '../../core/interface-types/float-types.js'
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-import IOComponent from './IOComponent.js'
-
-function meshIOComponentToJSComponent (emscriptenModule: IOEmscriptenModule, ioComponentType: typeof IOComponent[keyof typeof IOComponent]):
-  typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] | null {
-  let componentType = null
-  switch (ioComponentType) {
-    case emscriptenModule.IOComponentType.UNKNOWNCOMPONENTTYPE: {
-      componentType = null
-      break
-    }
-    case emscriptenModule.IOComponentType.UCHAR: {
-      componentType = IntTypes.UInt8
-      break
-    }
-    case emscriptenModule.IOComponentType.CHAR: {
-      componentType = IntTypes.Int8
-      break
-    }
-    case emscriptenModule.IOComponentType.USHORT: {
-      componentType = IntTypes.UInt16
-      break
-    }
-    case emscriptenModule.IOComponentType.SHORT: {
-      componentType = IntTypes.Int16
-      break
-    }
-    case emscriptenModule.IOComponentType.UINT: {
-      componentType = IntTypes.UInt32
-      break
-    }
-    case emscriptenModule.IOComponentType.INT: {
-      componentType = IntTypes.Int32
-      break
-    }
-    case emscriptenModule.IOComponentType.ULONG: {
-      componentType = IntTypes.UInt64
-      break
-    }
-    case emscriptenModule.IOComponentType.LONG: {
-      componentType = IntTypes.Int64
-      break
-    }
-    case emscriptenModule.IOComponentType.ULONGLONG: {
-      componentType = IntTypes.UInt64
-      break
-    }
-    case emscriptenModule.IOComponentType.LONGLONG: {
-      componentType = IntTypes.Int64
-      break
-    }
-    case emscriptenModule.IOComponentType.FLOAT: {
-      componentType = FloatTypes.Float32
-      break
-    }
-    case emscriptenModule.IOComponentType.DOUBLE: {
-      componentType = FloatTypes.Float64
-      break
-    }
-    default:
-      throw new Error('Unknown IO component type')
-  }
-
-  return componentType
-}
-
-export default meshIOComponentToJSComponent
diff --git a/src/io/internal/meshIOPixelTypeToJSPixelType.ts b/src/io/internal/meshIOPixelTypeToJSPixelType.ts
deleted file mode 100644
index 4bb61ef5a..000000000
--- a/src/io/internal/meshIOPixelTypeToJSPixelType.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import PixelTypes from '../../core/interface-types/pixel-types.js'
-import IOPixel from './IOPixel.js'
-
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-
-function meshIOPixelTypeToJSPixelType (emscriptenModule: IOEmscriptenModule, ioPixelType: typeof IOPixel[keyof typeof IOPixel]): typeof PixelTypes[keyof typeof PixelTypes] | null {
-  let pixelType = null
-  switch (ioPixelType) {
-    case emscriptenModule.IOPixelType.UNKNOWNPIXELTYPE: {
-      pixelType = PixelTypes.Unknown
-      break
-    }
-    case emscriptenModule.IOPixelType.SCALAR: {
-      pixelType = PixelTypes.Scalar
-      break
-    }
-    case emscriptenModule.IOPixelType.RGB: {
-      pixelType = PixelTypes.RGB
-      break
-    }
-    case emscriptenModule.IOPixelType.RGBA: {
-      pixelType = PixelTypes.RGBA
-      break
-    }
-    case emscriptenModule.IOPixelType.OFFSET: {
-      pixelType = PixelTypes.Offset
-      break
-    }
-    case emscriptenModule.IOPixelType.VECTOR: {
-      pixelType = PixelTypes.Vector
-      break
-    }
-    case emscriptenModule.IOPixelType.POINT: {
-      pixelType = PixelTypes.Point
-      break
-    }
-    case emscriptenModule.IOPixelType.COVARIANTVECTOR: {
-      pixelType = PixelTypes.CovariantVector
-      break
-    }
-    case emscriptenModule.IOPixelType.SYMMETRICSECONDRANKTENSOR: {
-      pixelType = PixelTypes.SymmetricSecondRankTensor
-      break
-    }
-    case emscriptenModule.IOPixelType.DIFFUSIONTENSOR3D: {
-      pixelType = PixelTypes.DiffusionTensor3D
-      break
-    }
-    case emscriptenModule.IOPixelType.COMPLEX: {
-      pixelType = PixelTypes.Complex
-      break
-    }
-    case emscriptenModule.IOPixelType.FIXEDARRAY: {
-      pixelType = PixelTypes.FixedArray
-      break
-    }
-    case emscriptenModule.IOPixelType.ARRAY: {
-      pixelType = PixelTypes.Array
-      break
-    }
-    case emscriptenModule.IOPixelType.MATRIX: {
-      pixelType = PixelTypes.Matrix
-      break
-    }
-    case emscriptenModule.IOPixelType.VARIABLELENGTHVECTOR: {
-      pixelType = PixelTypes.VariableLengthVector
-      break
-    }
-    case emscriptenModule.IOPixelType.VARIABLESIZEMATRIX: {
-      pixelType = PixelTypes.VariableSizeMatrix
-      break
-    }
-    default:
-      throw new Error('Unknown IO pixel type')
-  }
-  return pixelType
-}
-
-export default meshIOPixelTypeToJSPixelType
diff --git a/src/io/internal/meshJSComponentToIOComponent.ts b/src/io/internal/meshJSComponentToIOComponent.ts
deleted file mode 100644
index 980cc7988..000000000
--- a/src/io/internal/meshJSComponentToIOComponent.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import IntTypes from '../../core/interface-types/int-types.js'
-import FloatTypes from '../../core/interface-types/float-types.js'
-
-import IOComponent from './IOComponent.js'
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-
-function meshJSComponentToIOComponent (emscriptenModule: IOEmscriptenModule,
-  componentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes] | null): typeof IOComponent[keyof typeof IOComponent] | null {
-  let ioComponentType = null
-  switch (componentType) {
-    case null: {
-      ioComponentType = emscriptenModule.IOComponentType.UNKNOWNCOMPONENTTYPE
-      break
-    }
-    case IntTypes.UInt8: {
-      ioComponentType = emscriptenModule.IOComponentType.UCHAR
-      break
-    }
-    case IntTypes.Int8: {
-      ioComponentType = emscriptenModule.IOComponentType.CHAR
-      break
-    }
-    case IntTypes.UInt16: {
-      ioComponentType = emscriptenModule.IOComponentType.USHORT
-      break
-    }
-    case IntTypes.Int16: {
-      ioComponentType = emscriptenModule.IOComponentType.SHORT
-      break
-    }
-    case IntTypes.UInt32: {
-      ioComponentType = emscriptenModule.IOComponentType.UINT
-      break
-    }
-    case IntTypes.Int32: {
-      ioComponentType = emscriptenModule.IOComponentType.INT
-      break
-    }
-    case IntTypes.UInt64: {
-      ioComponentType = emscriptenModule.IOComponentType.ULONGLONG
-      break
-    }
-    case IntTypes.Int64: {
-      ioComponentType = emscriptenModule.IOComponentType.LONGLONG
-      break
-    }
-    case FloatTypes.Float32: {
-      ioComponentType = emscriptenModule.IOComponentType.FLOAT
-      break
-    }
-    case FloatTypes.Float64: {
-      ioComponentType = emscriptenModule.IOComponentType.DOUBLE
-      break
-    }
-    default:
-      throw new Error('Unknown IO component type')
-  }
-
-  return ioComponentType
-}
-
-export default meshJSComponentToIOComponent
diff --git a/src/io/internal/meshJSPixelTypeToIOPixelType.ts b/src/io/internal/meshJSPixelTypeToIOPixelType.ts
deleted file mode 100644
index 70f16a2eb..000000000
--- a/src/io/internal/meshJSPixelTypeToIOPixelType.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import PixelTypes from '../../core/interface-types/pixel-types.js'
-
-import IOPixel from './IOPixel.js'
-import IOEmscriptenModule from './IOEmscriptenModule.js'
-
-function meshJSPixelTypeToIOPixelType (emscriptenModule: IOEmscriptenModule,
-  pixelType: typeof PixelTypes[keyof typeof PixelTypes]): typeof IOPixel[keyof typeof IOPixel] {
-  let ioPixelType = null
-  switch (pixelType) {
-    case PixelTypes.Unknown: {
-      ioPixelType = emscriptenModule.IOPixelType.UNKNOWNPIXELTYPE
-      break
-    }
-    case PixelTypes.Scalar: {
-      ioPixelType = emscriptenModule.IOPixelType.SCALAR
-      break
-    }
-    case PixelTypes.RGB: {
-      ioPixelType = emscriptenModule.IOPixelType.RGB
-      break
-    }
-    case PixelTypes.RGBA: {
-      ioPixelType = emscriptenModule.IOPixelType.RGBA
-      break
-    }
-    case PixelTypes.Offset: {
-      ioPixelType = emscriptenModule.IOPixelType.OFFSET
-      break
-    }
-    case PixelTypes.Vector: {
-      ioPixelType = emscriptenModule.IOPixelType.VECTOR
-      break
-    }
-    case PixelTypes.Point: {
-      ioPixelType = emscriptenModule.IOPixelType.POINT
-      break
-    }
-    case PixelTypes.CovariantVector: {
-      ioPixelType = emscriptenModule.IOPixelType.COVARIANTVECTOR
-      break
-    }
-    case PixelTypes.SymmetricSecondRankTensor: {
-      ioPixelType = emscriptenModule.IOPixelType.SYMMETRICSECONDRANKTENSOR
-      break
-    }
-    case PixelTypes.DiffusionTensor3D: {
-      ioPixelType = emscriptenModule.IOPixelType.DIFFUSIONTENSOR3D
-      break
-    }
-    case PixelTypes.Complex: {
-      ioPixelType = emscriptenModule.IOPixelType.COMPLEX
-      break
-    }
-    case PixelTypes.FixedArray: {
-      ioPixelType = emscriptenModule.IOPixelType.FIXEDARRAY
-      break
-    }
-    case PixelTypes.Array: {
-      ioPixelType = emscriptenModule.IOPixelType.ARRAY
-      break
-    }
-    case PixelTypes.Matrix: {
-      ioPixelType = emscriptenModule.IOPixelType.MATRIX
-      break
-    }
-    case PixelTypes.VariableLengthVector: {
-      ioPixelType = emscriptenModule.IOPixelType.VARIABLELENGTHVECTOR
-      break
-    }
-    case PixelTypes.VariableSizeMatrix: {
-      ioPixelType = emscriptenModule.IOPixelType.VARIABLESIZEMATRIX
-      break
-    }
-    default:
-      throw new Error('Unknown IO pixel type')
-  }
-  return ioPixelType
-}
-export default meshJSPixelTypeToIOPixelType
diff --git a/src/io/internal/packages/README.image-io.md b/src/io/internal/packages/README.image-io.md
deleted file mode 100644
index 2b17994eb..000000000
--- a/src/io/internal/packages/README.image-io.md
+++ /dev/null
@@ -1,5 +0,0 @@
-itk-image-io
-------------
-
-
-Scientific image io with [itk-wasm](https://github.com/InsightSoftwareConsortium/itk-wasm.git).
diff --git a/src/io/internal/packages/README.mesh-io.md b/src/io/internal/packages/README.mesh-io.md
deleted file mode 100644
index f4eb8b9d8..000000000
--- a/src/io/internal/packages/README.mesh-io.md
+++ /dev/null
@@ -1,4 +0,0 @@
-itk-mesh-io
------------
-
-Scientific mesh io with [itk-wasm](https://github.com/InsightSoftwareConsortium/itk-wasm.git).
diff --git a/src/io/internal/packages/image-io.package.json.in b/src/io/internal/packages/image-io.package.json.in
deleted file mode 100644
index cd65105d1..000000000
--- a/src/io/internal/packages/image-io.package.json.in
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "name": "itk-image-io",
-  "version": "sem-ver",
-  "description": "Scientific image io with itk-wasm.",
-  "type": "module",
-  "main": "./index.js",
-  "scripts": {
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/InsightSoftwareConsortium/itk-wasm.git"
-  },
-  "keywords": [
-    "itk",
-    "imaging",
-    "wasm",
-    "webassembly",
-    "wasi",
-    "io",
-    "medical",
-    "scientific"
-  ],
-  "author": "Insight Software Consortium",
-  "license": "Apache-2.0",
-  "bugs": {
-    "url": "https://github.com/InsightSoftwareConsortium/itk-wasm/issues"
-  },
-  "homepage": "https://wasm.itk.org/",
-  "devDependencies": {
-  },
-  "dependencies": {
-  }
-}
diff --git a/src/io/internal/packages/mesh-io.package.json.in b/src/io/internal/packages/mesh-io.package.json.in
deleted file mode 100644
index e140722d9..000000000
--- a/src/io/internal/packages/mesh-io.package.json.in
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "name": "itk-mesh-io",
-  "version": "sem-ver",
-  "description": "Scientific mesh io with itk-wasm.",
-  "type": "module",
-  "main": "./index.js",
-  "scripts": {
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/InsightSoftwareConsortium/itk-wasm.git"
-  },
-  "keywords": [
-    "itk",
-    "mesh",
-    "wasm",
-    "webassembly",
-    "wasi",
-    "io",
-    "medical",
-    "scientific"
-  ],
-  "author": "Insight Software Consortium",
-  "license": "Apache-2.0",
-  "bugs": {
-    "url": "https://github.com/InsightSoftwareConsortium/itk-wasm/issues"
-  },
-  "homepage": "https://wasm.itk.org/",
-  "devDependencies": {
-  },
-  "dependencies": {
-  }
-}
diff --git a/src/io/internal/packages/package-json-gen.cjs b/src/io/internal/packages/package-json-gen.cjs
deleted file mode 100755
index 89b344be4..000000000
--- a/src/io/internal/packages/package-json-gen.cjs
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env node
-
-const path = require('path')
-const fs = require('fs-extra')
-
-mainPackageFile = fs.readFileSync(path.join('package.json'))
-mainPackage = JSON.parse(mainPackageFile)
-version = mainPackage.version
-
-const packages = ['image-io', 'mesh-io']
-packages.forEach((packageName) => {
-  const templateFile = fs.readFileSync(path.join(__dirname, `${packageName}.package.json.in`))
-  const template = JSON.parse(templateFile)
-  template.version = version
-  template.dependencies['itk-wasm'] = version
-  fs.writeFileSync(path.join('dist', packageName, 'package.json'), JSON.stringify(template))
-  readmeFile = path.join(__dirname, `README.${packageName}.md`)
-  fs.copyFileSync(readmeFile, path.join('dist', packageName, 'README.md'))
-})
diff --git a/src/io/internal/pipelines/image/convert-image/CMakeLists.txt b/src/io/internal/pipelines/image/convert-image/CMakeLists.txt
deleted file mode 100644
index d0480b4cd..000000000
--- a/src/io/internal/pipelines/image/convert-image/CMakeLists.txt
+++ /dev/null
@@ -1,197 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(convert-image)
-
-set(CMAKE_CXX_STANDARD 17)
-
-if (NOT TARGET libzstd_static)
-  include(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../CMake/BuildZstd.cmake)
-endif()
-
-if(WASI)
-  set(WebAssemblyInterface_ImageIOModules
-    "ITKIOPNG"
-    "ITKIOMeta"
-    "ITKIOTIFF"
-    "ITKIONIFTI"
-    "ITKIOJPEG"
-    "ITKIONRRD"
-    "ITKIOVTK"
-    "ITKIOBMP"
-    "ITKIOMRC"
-    "ITKIOLSM"
-    "MGHIO"
-    "ITKIOBioRad"
-    "ITKIOGIPL"
-    "ITKIOGE"
-    "ITKIOGDCM"
-    "IOScanco"
-    "IOFDF"
-    CACHE STRING
-    "String delimited list of ITK image IO modules to support.")
-else()
-  # This list should be ordered from approximately most commonly to least
-  # commonly used modules.
-  set(WebAssemblyInterface_ImageIOModules
-    "ITKIOPNG"
-    "ITKIOMeta"
-    "ITKIOTIFF"
-    "ITKIONIFTI"
-    "ITKIOJPEG"
-    "ITKIONRRD"
-    "ITKIOVTK"
-    "ITKIOBMP"
-    "ITKIOHDF5"
-    "ITKIOMINC"
-    "ITKIOMRC"
-    "ITKIOLSM"
-    "MGHIO"
-    "ITKIOBioRad"
-    "ITKIOGIPL"
-    "ITKIOGE"
-    "ITKIOGDCM"
-    "IOScanco"
-    "IOFDF"
-    CACHE STRING
-    "String delimited list of ITK image IO modules to support.")
-endif()
-set(imageios_ITKIOPNG itkPNGImageIO)
-set(imageio_id_itkPNGImageIO 0)
-
-set(imageios_ITKIOMeta itkMetaImageIO)
-set(imageio_id_itkMetaImageIO 1)
-
-set(imageios_ITKIOTIFF itkTIFFImageIO)
-set(imageio_id_itkTIFFImageIO 2)
-
-set(imageios_ITKIONIFTI itkNiftiImageIO)
-set(imageio_id_itkNiftiImageIO 3)
-
-set(imageios_ITKIOJPEG itkJPEGImageIO)
-set(imageio_id_itkJPEGImageIO 4)
-
-set(imageios_ITKIONRRD itkNrrdImageIO)
-set(imageio_id_itkNrrdImageIO 5)
-
-set(imageios_ITKIOVTK itkVTKImageIO)
-set(imageio_id_itkVTKImageIO 6)
-
-set(imageios_ITKIOBMP itkBMPImageIO)
-set(imageio_id_itkBMPImageIO 7)
-
-set(imageios_ITKIOHDF5 itkHDF5ImageIO)
-set(imageio_id_itkHDF5ImageIO 8)
-
-set(imageios_ITKIOMINC itkMINCImageIO)
-set(imageio_id_itkMINCImageIO 9)
-
-set(imageios_ITKIOMRC itkMRCImageIO)
-set(imageio_id_itkMRCImageIO 10)
-
-set(imageios_ITKIOLSM itkLSMImageIO)
-set(imageio_id_itkLSMImageIO 11)
-
-set(imageios_MGHIO itkMGHImageIO)
-set(imageio_id_itkMGHImageIO 12)
-
-set(imageios_ITKIOBioRad itkBioRadImageIO)
-set(imageio_id_itkBioRadImageIO 13)
-
-set(imageios_ITKIOGIPL itkGiplImageIO)
-set(imageio_id_itkGiplImageIO 14)
-
-set(imageios_ITKIOGE itkGEAdwImageIO itkGE4ImageIO itkGE5ImageIO)
-set(imageio_id_itkGE4ImageIO 15)
-set(imageio_id_itkGE5ImageIO 16)
-set(imageio_id_itkGEAdwImageIO 17)
-
-set(imageios_ITKIOGDCM itkGDCMImageIO)
-set(imageio_id_itkGDCMImageIO 18)
-
-set(imageios_IOScanco itkScancoImageIO)
-set(imageio_id_itkScancoImageIO 19)
-
-set(imageios_IOFDF itkFDFImageIO)
-set(imageio_id_itkFDFImageIO 20)
-
-set(imageios_WebAssemblyInterface itkWasmImageIO itkWasmZstdImageIO)
-set(imageio_id_itkWasmImageIO 21)
-set(imageio_id_itkWasmZstdImageIO 22)
-
-set(ITK_NO_IMAGEIO_FACTORY_REGISTER_MANAGER 1)
-set(ImageIOIndex_ARRAY "")
-foreach(io_module ${WebAssemblyInterface_ImageIOModules} WebAssemblyInterface)
-  if (DEFINED WebAssemblyInterface_INCLUDE_DIRS)
-    if(${io_module} STREQUAL "WebAssemblyInterface")
-      find_package(ITK REQUIRED COMPONENTS ITKIOImageBase)
-      include(${ITK_USE_FILE})
-      include_directories(${WebAssemblyInterface_INCLUDE_DIRS})
-      include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-      list(APPEND ITK_LIBRARIES ${WebAssemblyInterface_LIBRARIES})
-    else()
-      find_package(ITK REQUIRED COMPONENTS ${io_module} WebAssemblyInterface)
-      include(${ITK_USE_FILE})
-    endif()
-  else()
-    find_package(ITK REQUIRED COMPONENTS ${io_module} WebAssemblyInterface)
-    include(${ITK_USE_FILE})
-  endif()
-
-  if(NOT DEFINED imageios_${io_module})
-    message(FATAL_ERROR "Unknown ImageIOBase classes for module ${io_module}")
-  endif()
-  foreach(imageio ${imageios_${io_module}})
-    string(SUBSTRING "${imageio}" 3 -1 ioname)
-    set(read_binary "${ioname}-read-image")
-    set(write_binary "${ioname}-write-image")
-    set(ImageIOIndex_ARRAY "${ImageIOIndex_ARRAY}'${ioname}', ")
-    set(extra_srcs)
-    if(${imageio} STREQUAL "itkWasmZstdImageIO")
-      list(APPEND ITK_LIBRARIES libzstd_static)
-      list(APPEND extra_srcs itkWasmZstdImageIO.cxx)
-    endif()
-
-    add_executable(${read_binary} read-image.cxx ${extra_srcs})
-    target_link_libraries(${read_binary} PUBLIC ${ITK_LIBRARIES})
-    target_compile_definitions(${read_binary} PUBLIC -DIMAGE_IO_CLASS=${imageio_id_${imageio}})
-    add_executable(${write_binary} write-image.cxx ${extra_srcs})
-    target_link_libraries(${write_binary} PUBLIC ${ITK_LIBRARIES})
-    target_compile_definitions(${write_binary} PUBLIC -DIMAGE_IO_CLASS=${imageio_id_${imageio}})
-    if (EMSCRIPTEN AND DEFINED WebAssemblyInterface_BINARY_DIR)
-      set(target_esm_read "${read_binary}")
-      set(target_esm_write "${write_binary}")
-      foreach(target ${target_esm_read} ${target_esm_write})
-        set(exception_catching )
-        if(${io_module} STREQUAL "ITKIOGE")
-          set(exception_catching " -s DISABLE_EXCEPTION_CATCHING=0")
-        endif()
-        set(imageio_common_link_flags " -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s SUPPORT_LONGJMP=1")
-        get_property(link_flags TARGET ${target} PROPERTY LINK_FLAGS)
-        set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${imageio_common_link_flags} ${link_flags}")
-        itk_module_target_label(${target})
-        itk_module_target_export(${target})
-        itk_module_target_install(${target})
-        set_property(TARGET ${target}
-          PROPERTY RUNTIME_OUTPUT_DIRECTORY
-          ${WebAssemblyInterface_BINARY_DIR}/image-io
-          )
-      endforeach()
-    elseif (WASI AND DEFINED WebAssemblyInterface_BINARY_DIR)
-      foreach(target ${read_binary} ${write_binary})
-        set(exception_catching )
-        itk_module_target_label(${target})
-        itk_module_target_export(${target})
-        itk_module_target_install(${target})
-        set_property(TARGET ${target}
-          PROPERTY RUNTIME_OUTPUT_DIRECTORY
-          ${WebAssemblyInterface_BINARY_DIR}/wasi-image-io
-          )
-      endforeach()
-    endif()
-  endforeach()
-endforeach()
-if(EMSCRIPTEN)
-  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../../ImageIOIndex.ts.in
-    ${CMAKE_CURRENT_SOURCE_DIR}/../../../ImageIOIndex.ts @ONLY)
-  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../../ImageIOIndex.ts.in
-    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../dist/image-io/index.js @ONLY)
-endif()
diff --git a/src/io/internal/pipelines/image/convert-image/itkWasmZstdImageIO.cxx b/src/io/internal/pipelines/image/convert-image/itkWasmZstdImageIO.cxx
deleted file mode 100644
index 39ffa3016..000000000
--- a/src/io/internal/pipelines/image/convert-image/itkWasmZstdImageIO.cxx
+++ /dev/null
@@ -1,194 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-
-#include "itkWasmZstdImageIO.h"
-#include "zstd.h"
-
-namespace itk
-{
-
-WasmZstdImageIO
-::WasmZstdImageIO()
-{
-  this->AddSupportedWriteExtension(".iwi.cbor.zst");
-  this->AddSupportedReadExtension(".iwi.cbor.zst");
-}
-
-
-WasmZstdImageIO
-::~WasmZstdImageIO()
-{
-}
-
-
-bool
-WasmZstdImageIO
-::CanReadFile(const char *filename)
-{
-  std::string fname = filename;
-
-  bool extensionFound = false;
-  std::string::size_type extensionPos = fname.rfind(".iwi");
-  if ( extensionPos != std::string::npos )
-    {
-    extensionFound = true;
-    }
-
-  if ( !extensionFound )
-    {
-    itkDebugMacro(<< "The filename extension is not recognized");
-    return false;
-    }
-
-  return true;
-}
-
-
-
-void
-WasmZstdImageIO
-::ReadImageInformation()
-{
-  this->SetByteOrderToLittleEndian();
-
-  const std::string path = this->GetFileName();
-
-  std::string::size_type zstdPos = path.rfind(".zst");
-  if ( ( zstdPos != std::string::npos )
-       && ( zstdPos == path.length() - 4 ) )
-  {
-    std::ifstream dataStream;
-    this->OpenFileForReading( dataStream, this->GetFileName() );
-
-    std::ostringstream ostrm;
-    ostrm << dataStream.rdbuf();
-    auto inputBinary = ostrm.str();
-
-    const size_t decompressedBufferSize = ZSTD_getFrameContentSize(inputBinary.data(), inputBinary.size());
-    std::vector<char> decompressedBinary(decompressedBufferSize);
-
-    const size_t decompressedSize = ZSTD_decompress(decompressedBinary.data(), decompressedBufferSize, inputBinary.data(), inputBinary.size());
-    decompressedBinary.resize(decompressedSize);
-
-    this->ReadCBOR(nullptr, reinterpret_cast< unsigned char *>(&(decompressedBinary.at(0))), decompressedSize);
-    return;
-  }
-
-  Superclass::ReadImageInformation();
-}
-
-
-void
-WasmZstdImageIO
-::Read( void *buffer )
-{
-  const std::string path = this->GetFileName();
-  std::string::size_type zstdPos = path.rfind(".zst");
-  if ( ( zstdPos != std::string::npos )
-       && ( zstdPos == path.length() - 4 ) )
-  {
-    std::ifstream dataStream;
-    this->OpenFileForReading( dataStream, this->GetFileName() );
-
-    std::ostringstream ostrm;
-    ostrm << dataStream.rdbuf();
-    auto inputBinary = ostrm.str();
-
-
-    const size_t decompressedBufferSize = ZSTD_getFrameContentSize(inputBinary.data(), inputBinary.size());
-    std::vector<char> decompressedBinary(decompressedBufferSize);
-
-    const size_t decompressedSize = ZSTD_decompress(decompressedBinary.data(), decompressedBufferSize, inputBinary.data(), inputBinary.size());
-    decompressedBinary.resize(decompressedSize);
-
-    this->ReadCBOR(buffer, reinterpret_cast< unsigned char *>(&(decompressedBinary.at(0))), decompressedSize);
-    return;
-  }
-
-  Superclass::Read(buffer);
-}
-
-
-bool
-WasmZstdImageIO
-::CanWriteFile(const char *name)
-{
-  std::string filename = name;
-
-  if( filename == "" )
-    {
-    return false;
-    }
-
-  bool extensionFound = false;
-  std::string::size_type iwiPos = filename.rfind(".iwi");
-  if ( iwiPos != std::string::npos )
-    {
-    extensionFound = true;
-    }
-
-  if ( !extensionFound )
-    {
-    itkDebugMacro(<< "The filename extension is not recognized");
-    return false;
-    }
-
-  return true;
-}
-
-
-void
-WasmZstdImageIO
-::WriteImageInformation()
-{
-  Superclass::WriteImageInformation();
-}
-
-
-void
-WasmZstdImageIO
-::Write( const void *buffer )
-{
-  const std::string path(this->GetFileName());
-
-  std::string::size_type cborPos = path.rfind(".zst");
-  if ( ( cborPos != std::string::npos )
-       && ( cborPos == path.length() - 4 ) )
-  {
-    unsigned char * inputBinary;
-    const size_t inputBinarySize = this->WriteCBOR(buffer, &inputBinary, true);
-
-    const size_t compressedBufferSize = ZSTD_compressBound(inputBinarySize);
-    std::vector<char> compressedBinary(compressedBufferSize);
-
-    constexpr int compressionLevel = 3;
-    const size_t compressedSize = ZSTD_compress(compressedBinary.data(), compressedBufferSize, inputBinary, inputBinarySize, compressionLevel);
-    free(inputBinary);
-    compressedBinary.resize(compressedSize);
-
-    std::ofstream outputStream;
-    this->OpenFileForWriting( outputStream, path.c_str(), true, false );
-    std::ostream_iterator<char> oIt(outputStream);
-    std::copy(compressedBinary.begin(), compressedBinary.end(), oIt);
-    return;
-  }
-
-  Superclass::Write( buffer );
-}
-
-} // end namespace itk
diff --git a/src/io/internal/pipelines/image/convert-image/itkWasmZstdImageIO.h b/src/io/internal/pipelines/image/convert-image/itkWasmZstdImageIO.h
deleted file mode 100644
index 0c7c7be12..000000000
--- a/src/io/internal/pipelines/image/convert-image/itkWasmZstdImageIO.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#ifndef itkWasmZstdImageIO_h
-#define itkWasmZstdImageIO_h
-#include "WebAssemblyInterfaceExport.h"
-
-#include "itkWasmImageIO.h"
-
-namespace itk
-{
-/** \class WasmZstdImageIO
- *
- * \brief Read and write an itk::Image in a web-friendly format.
- *
- * This format is intended to facilitate data exchange in itk-wasm.
- * It reads and writes an itk-wasm Image object in a CbOR file on the
- * filesystem with JSON files and binary files for TypedArrays.
- * 
- * This class extends WasmImageIO by adding support for zstandard compression.
- *
- * The file extensions used are .iwi, .iwi.cbor, and .iwi.cbor.zst.
- * 
- * \ingroup IOFilters
- * \ingroup WebAssemblyInterface
- */
-class WebAssemblyInterface_EXPORT WasmZstdImageIO: public WasmImageIO
-{
-public:
-  /** Standard class typedefs. */
-  typedef WasmZstdImageIO      Self;
-  typedef WasmImageIO          Superclass;
-  typedef SmartPointer< Self > Pointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(WasmZstdImageIO, WasmImageIO);
-
-  /** Determine the file type. Returns true if this ImageIO can read the
-   * file specified. */
-  bool CanReadFile(const char *) override;
-
-  /** Set the spacing and dimension information for the set filename. */
-  void ReadImageInformation() override;
-
-  /** Reads the data from disk into the memory buffer provided. */
-  void Read(void *buffer) override;
-
-  /** Determine the file type. Returns true if this ImageIO can write the
-   * file specified. */
-  bool CanWriteFile(const char *) override;
-
-  /** Set the spacing and dimension information for the set filename. */
-  void WriteImageInformation() override;
-
-  /** Writes the data to disk from the memory buffer provided. Make sure
-   * that the IORegions has been set properly. */
-  void Write(const void *buffer) override;
-
-protected:
-  WasmZstdImageIO();
-  ~WasmZstdImageIO() override;
-
-private:
-  ITK_DISALLOW_COPY_AND_ASSIGN(WasmZstdImageIO);
-};
-} // end namespace itk
-
-#endif // itkWasmZstdImageIO_h
diff --git a/src/io/internal/pipelines/image/convert-image/read-image.cxx b/src/io/internal/pipelines/image/convert-image/read-image.cxx
deleted file mode 100644
index 122114ba0..000000000
--- a/src/io/internal/pipelines/image/convert-image/read-image.cxx
+++ /dev/null
@@ -1,167 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#include "itkCommonEnums.h"
-#include "itkImageIOBase.h"
-#include "itkImage.h"
-#include "itkOutputImageIO.h"
-
-#ifndef IMAGE_IO_CLASS
-#error "IMAGE_IO_CLASS definition must be provided"
-#endif
-
-#if IMAGE_IO_CLASS == 0
-#include "itkPNGImageIO.h"
-#elif IMAGE_IO_CLASS == 1
-#include "itkMetaImageIO.h"
-#elif IMAGE_IO_CLASS == 2
-#include "itkTIFFImageIO.h"
-#elif IMAGE_IO_CLASS == 3
-#include "itkNiftiImageIO.h"
-#elif IMAGE_IO_CLASS == 4
-#include "itkJPEGImageIO.h"
-#elif IMAGE_IO_CLASS == 5
-#include "itkNrrdImageIO.h"
-#elif IMAGE_IO_CLASS == 6
-#include "itkVTKImageIO.h"
-#elif IMAGE_IO_CLASS == 7
-#include "itkBMPImageIO.h"
-#elif IMAGE_IO_CLASS == 8
-#include "itkHDF5ImageIO.h"
-#elif IMAGE_IO_CLASS == 9
-#include "itkMINCImageIO.h"
-#elif IMAGE_IO_CLASS == 10
-#include "itkMRCImageIO.h"
-#elif IMAGE_IO_CLASS == 11
-#include "itkLSMImageIO.h"
-#elif IMAGE_IO_CLASS == 12
-#include "itkMGHImageIO.h"
-#elif IMAGE_IO_CLASS == 13
-#include "itkBioRadImageIO.h"
-#elif IMAGE_IO_CLASS == 14
-#include "itkGiplImageIO.h"
-#elif IMAGE_IO_CLASS == 15
-#include "itkGE4ImageIO.h"
-#elif IMAGE_IO_CLASS == 16
-#include "itkGE5ImageIO.h"
-#elif IMAGE_IO_CLASS == 17
-#include "itkGEAdwImageIO.h"
-#elif IMAGE_IO_CLASS == 18
-#include "itkGDCMImageIO.h"
-#elif IMAGE_IO_CLASS == 19
-#include "itkScancoImageIO.h"
-#elif IMAGE_IO_CLASS == 20
-#include "itkFDFImageIO.h"
-#elif IMAGE_IO_CLASS == 21
-#elif IMAGE_IO_CLASS == 22
-#include "itkWasmZstdImageIO.h"
-#else
-#error "Unsupported IMAGE_IO_CLASS"
-#endif
-#include "itkWasmImageIO.h"
-
-#include "itkPipeline.h"
-#include "itkOutputImage.h"
-
-template <typename TImageIO>
-int readImage(const std::string & inputFileName, itk::wasm::OutputImageIO & outputImageIO, bool quiet)
-{
-  using ImageIOType = TImageIO;
-
-  auto imageIO = ImageIOType::New();
-
-  if(!imageIO->CanReadFile(inputFileName.c_str()))
-  {
-    if(!quiet)
-    {
-      std::cerr << "Could not read file: " << inputFileName << std::endl;
-    }
-    return EXIT_FAILURE;
-  }
-
-  imageIO->SetFileName(inputFileName);
-  outputImageIO.Set(imageIO);
-
-  return EXIT_SUCCESS;
-}
-
-int main (int argc, char * argv[])
-{
-  itk::wasm::Pipeline pipeline("read-image", "Read an image file format and convert it to the itk-wasm file format", argc, argv);
-
-  std::string inputFileName;
-  pipeline.add_option("input-image", inputFileName, "Input image")->required()->check(CLI::ExistingFile);
-
-  itk::wasm::OutputImageIO outputImageIO;
-  pipeline.add_option("OutputImage", outputImageIO, "Output image")->required();
-
-  bool quiet = false;
-  pipeline.add_flag("-q,--quiet", quiet, "Less verbose output");
-  
-  ITK_WASM_PARSE(pipeline);
-
-#if IMAGE_IO_CLASS == 0
-  return readImage<itk::PNGImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 1
-  return readImage<itk::MetaImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 2
-  return readImage<itk::TIFFImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 3
-  return readImage<itk::NiftiImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 4
-  return readImage<itk::JPEGImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 5
-  return readImage<itk::NrrdImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 6
-  return readImage<itk::VTKImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 7
-  return readImage<itk::BMPImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 8
-  return readImage<itk::HDF5ImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 9
-  return readImage<itk::MINCImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 10
-  return readImage<itk::MRCImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 11
-  return readImage<itk::LSMImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 12
-  return readImage<itk::MGHImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 13
-  return readImage<itk::BioRadImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 14
-  return readImage<itk::GiplImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 15
-  return readImage<itk::GE4ImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 16
-  return readImage<itk::GE5ImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 17
-  return readImage<itk::GEAdwImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 18
-  return readImage<itk::GDCMImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 19
-  return readImage<itk::ScancoImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 20
-  return readImage<itk::FDFImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 21
-  return readImage<itk::WasmImageIO>(inputFileName, outputImageIO, quiet);
-#elif IMAGE_IO_CLASS == 22
-  return readImage<itk::WasmZstdImageIO>(inputFileName, outputImageIO, quiet);
-#else
-#error "Unsupported IMAGE_IO_CLASS"
-#endif
-  return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/src/io/internal/pipelines/image/convert-image/write-image.cxx b/src/io/internal/pipelines/image/convert-image/write-image.cxx
deleted file mode 100644
index afd387617..000000000
--- a/src/io/internal/pipelines/image/convert-image/write-image.cxx
+++ /dev/null
@@ -1,203 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#include "itkCommonEnums.h"
-#include "itkImageIOBase.h"
-#include "itkImage.h"
-#include "itkInputImageIO.h"
-
-#ifndef IMAGE_IO_CLASS
-#error "IMAGE_IO_CLASS definition must be provided"
-#endif
-
-#if IMAGE_IO_CLASS == 0
-#include "itkPNGImageIO.h"
-#elif IMAGE_IO_CLASS == 1
-#include "itkMetaImageIO.h"
-#elif IMAGE_IO_CLASS == 2
-#include "itkTIFFImageIO.h"
-#elif IMAGE_IO_CLASS == 3
-#include "itkNiftiImageIO.h"
-#elif IMAGE_IO_CLASS == 4
-#include "itkJPEGImageIO.h"
-#elif IMAGE_IO_CLASS == 5
-#include "itkNrrdImageIO.h"
-#elif IMAGE_IO_CLASS == 6
-#include "itkVTKImageIO.h"
-#elif IMAGE_IO_CLASS == 7
-#include "itkBMPImageIO.h"
-#elif IMAGE_IO_CLASS == 8
-#include "itkHDF5ImageIO.h"
-#elif IMAGE_IO_CLASS == 9
-#include "itkMINCImageIO.h"
-#elif IMAGE_IO_CLASS == 10
-#include "itkMRCImageIO.h"
-#elif IMAGE_IO_CLASS == 11
-#include "itkLSMImageIO.h"
-#elif IMAGE_IO_CLASS == 12
-#include "itkMGHImageIO.h"
-#elif IMAGE_IO_CLASS == 13
-#include "itkBioRadImageIO.h"
-#elif IMAGE_IO_CLASS == 14
-#include "itkGiplImageIO.h"
-#elif IMAGE_IO_CLASS == 15
-#include "itkGE4ImageIO.h"
-#elif IMAGE_IO_CLASS == 16
-#include "itkGE5ImageIO.h"
-#elif IMAGE_IO_CLASS == 17
-#include "itkGEAdwImageIO.h"
-#elif IMAGE_IO_CLASS == 18
-#include "itkGDCMImageIO.h"
-#elif IMAGE_IO_CLASS == 19
-#include "itkScancoImageIO.h"
-#elif IMAGE_IO_CLASS == 20
-#include "itkFDFImageIO.h"
-#elif IMAGE_IO_CLASS == 21
-#elif IMAGE_IO_CLASS == 22
-#include "itkWasmZstdImageIO.h"
-#else
-#error "Unsupported IMAGE_IO_CLASS"
-#endif
-#include "itkWasmImageIO.h"
-
-#include "itkPipeline.h"
-#include "itkOutputImage.h"
-#include "itkWasmImageIOBase.h"
-#include "itkImageIOBase.h"
-
-template <typename TImageIO>
-int writeImage(itk::wasm::InputImageIO & inputImageIO, const std::string & outputFileName, bool quiet, bool useCompression)
-{
-  using ImageIOType = TImageIO;
-
-  auto imageIO = ImageIOType::New();
-
-  if(!imageIO->CanWriteFile(outputFileName.c_str()))
-  {
-    if(!quiet)
-    {
-      std::cerr << "Could not write file: " << outputFileName << std::endl;
-    }
-    return EXIT_FAILURE;
-  }
-
-  imageIO->SetFileName(outputFileName);
-  imageIO->SetUseCompression(useCompression);
-
-  const itk::WasmImageIOBase * inputWasmImageIOBase = inputImageIO.Get();
-  const itk::ImageIOBase * inputImageIOBase = inputWasmImageIOBase->GetImageIO();
-
-  const unsigned int dimension = inputImageIOBase->GetNumberOfDimensions();
-  imageIO->SetNumberOfDimensions(dimension);
-  imageIO->SetComponentType(inputImageIOBase->GetComponentType());
-  imageIO->SetNumberOfComponents(inputImageIOBase->GetNumberOfComponents());
-  imageIO->SetPixelType(inputImageIOBase->GetPixelType());
-  std::vector<double> direction(dimension);
-  const auto directionContainer = inputWasmImageIOBase->GetDirectionContainer();
-  for (unsigned int dim = 0; dim < dimension; ++dim)
-  {
-    for (unsigned int dd = 0; dd < dimension; ++dd)
-    {
-      direction[dd] = directionContainer->GetElement(dim*dimension + dd);
-    }
-    imageIO->SetDirection(dim, direction);
-    imageIO->SetOrigin(dim, inputImageIOBase->GetOrigin(dim));
-    imageIO->SetSpacing(dim, inputImageIOBase->GetSpacing(dim));
-    imageIO->SetDimensions(dim, inputImageIOBase->GetDimensions(dim));
-  };
-  itk::ImageIORegion ioRegion( dimension );
-  for(unsigned int dim = 0; dim < dimension; ++dim)
-    {
-    ioRegion.SetSize(dim, inputImageIOBase->GetDimensions( dim ));
-    }
-  imageIO->SetIORegion( ioRegion );
-
-  imageIO->WriteImageInformation();
-  imageIO->Write( reinterpret_cast< const void * >( &(inputWasmImageIOBase->GetPixelDataContainer()->at(0)) ));
-
-  return EXIT_SUCCESS;
-}
-
-int main (int argc, char * argv[])
-{
-  itk::wasm::Pipeline pipeline("write-image", "Write an itk-wasm file format converted to an image file format", argc, argv);
-
-  itk::wasm::InputImageIO inputImageIO;
-  pipeline.add_option("input-image", inputImageIO, "Input image")->required();
-
-  std::string outputFileName;
-  pipeline.add_option("output-image", outputFileName, "Output image")->required();
-
-  bool quiet = false;
-  pipeline.add_flag("-q,--quiet", quiet, "Less verbose output");
-  
-  bool useCompression = false;
-  pipeline.add_flag("-c,--use-compression", quiet, "Use compression in the written file");
-  
-  ITK_WASM_PARSE(pipeline);
-
-#if IMAGE_IO_CLASS == 0
-  return writeImage<itk::PNGImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 1
-  return writeImage<itk::MetaImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 2
-  return writeImage<itk::TIFFImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 3
-  return writeImage<itk::NiftiImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 4
-  return writeImage<itk::JPEGImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 5
-  return writeImage<itk::NrrdImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 6
-  return writeImage<itk::VTKImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 7
-  return writeImage<itk::BMPImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 8
-  return writeImage<itk::HDF5ImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 9
-  return writeImage<itk::MINCImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 10
-  return writeImage<itk::MRCImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 11
-  return writeImage<itk::LSMImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 12
-  return writeImage<itk::MGHImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 13
-  return writeImage<itk::BioRadImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 14
-  return writeImage<itk::GiplImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 15
-  return writeImage<itk::GE4ImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 16
-  return writeImage<itk::GE5ImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 17
-  return writeImage<itk::GEAdwImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 18
-  return writeImage<itk::GDCMImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 19
-  return writeImage<itk::ScancoImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 20
-  return writeImage<itk::FDFImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 21
-  return writeImage<itk::WasmImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#elif IMAGE_IO_CLASS == 22
-  return writeImage<itk::WasmZstdImageIO>(inputImageIO, outputFileName, quiet, useCompression);
-#else
-#error "Unsupported IMAGE_IO_CLASS"
-#endif
-  return EXIT_SUCCESS;
-}
\ No newline at end of file
diff --git a/src/io/internal/pipelines/mesh/convert-mesh/CMakeLists.txt b/src/io/internal/pipelines/mesh/convert-mesh/CMakeLists.txt
deleted file mode 100644
index 4f2081962..000000000
--- a/src/io/internal/pipelines/mesh/convert-mesh/CMakeLists.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(ConvertMesh)
-
-set(CMAKE_CXX_STANDARD 17)
-
-if (NOT TARGET libzstd_static)
-  include(${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../CMake/BuildZstd.cmake)
-endif()
-
-# This list should be ordered from approximately most commonly to least
-# commonly used modules.
-set(WebAssemblyInterface_MeshIOModules
-  "ITKIOMeshBYU"
-  "ITKIOMeshFreeSurfer"
-  "ITKIOMeshOBJ"
-  "ITKIOMeshOFF"
-  "IOMeshSTL"
-  "IOMeshSWC"
-  "ITKIOMeshVTK"
-  CACHE STRING
-  "String delimited list of ITK mesh IO modules to support.")
-
-set(meshios_ITKIOMeshBYU itkBYUMeshIO)
-set(meshio_id_itkBYUMeshIO 0)
-
-set(meshios_ITKIOMeshFreeSurfer itkFreeSurferAsciiMeshIO itkFreeSurferBinaryMeshIO)
-set(meshio_id_itkFreeSurferAsciiMeshIO 1)
-set(meshio_id_itkFreeSurferBinaryMeshIO 2)
-
-set(meshios_ITKIOMeshVTK itkVTKPolyDataMeshIO)
-set(meshio_id_itkVTKPolyDataMeshIO 3)
-
-set(meshios_ITKIOMeshOBJ itkOBJMeshIO)
-set(meshio_id_itkOBJMeshIO 4)
-
-set(meshios_ITKIOMeshOFF itkOFFMeshIO)
-set(meshio_id_itkOFFMeshIO 5)
-
-set(meshios_IOMeshSTL itkSTLMeshIO)
-set(meshio_id_itkSTLMeshIO 6)
-
-set(meshios_IOMeshSWC itkSWCMeshIO)
-set(meshio_id_itkSWCMeshIO 7)
-
-set(meshios_WebAssemblyInterface itkWasmMeshIO itkWasmZstdMeshIO)
-set(meshio_id_itkWasmMeshIO 8)
-set(meshio_id_itkWasmZstdMeshIO 9)
-
-set(ITK_NO_MESHIO_FACTORY_REGISTER_MANAGER 1)
-set(MeshIOIndex_ARRAY "")
-foreach(io_module ${WebAssemblyInterface_MeshIOModules} WebAssemblyInterface)
-  if (DEFINED WebAssemblyInterface_INCLUDE_DIRS)
-    if(${io_module} STREQUAL "WebAssemblyInterface")
-      find_package(ITK REQUIRED COMPONENTS ITKIOMeshBase)
-      include(${ITK_USE_FILE})
-      include_directories(${WebAssemblyInterface_INCLUDE_DIRS})
-      include_directories(${CMAKE_CURRENT_SOURCE_DIR})
-      list(APPEND ITK_LIBRARIES ${WebAssemblyInterface_LIBRARIES})
-    else()
-      find_package(ITK REQUIRED COMPONENTS ${io_module} WebAssemblyInterface)
-      include(${ITK_USE_FILE})
-    endif()
-  else()
-    find_package(ITK REQUIRED COMPONENTS ${io_module} WebAssemblyInterface)
-    include(${ITK_USE_FILE})
-  endif()
-
-  if(NOT DEFINED meshios_${io_module})
-    message(FATAL_ERROR "Unknown MeshIOBase classes for module ${io_module}")
-  endif()
-  foreach(meshio ${meshios_${io_module}})
-    string(SUBSTRING "${meshio}" 3 -1 ioname)
-    set(read_binary "${ioname}-read-mesh")
-    set(write_binary "${ioname}-write-mesh")
-    set(MeshIOIndex_ARRAY "${MeshIOIndex_ARRAY}'${ioname}', ")
-    set(extra_srcs)
-    if(${meshio} STREQUAL "itkWasmZstdMeshIO")
-      list(APPEND ITK_LIBRARIES libzstd_static)
-      list(APPEND extra_srcs itkWasmZstdMeshIO.cxx)
-    endif()
-
-    add_executable(${read_binary} read-mesh.cxx ${extra_srcs})
-    target_link_libraries(${read_binary} PUBLIC ${ITK_LIBRARIES})
-    target_compile_definitions(${read_binary} PUBLIC -DMESH_IO_CLASS=${meshio_id_${meshio}})
-    add_executable(${write_binary} write-mesh.cxx ${extra_srcs})
-    target_link_libraries(${write_binary} PUBLIC ${ITK_LIBRARIES})
-    target_compile_definitions(${write_binary} PUBLIC -DMESH_IO_CLASS=${meshio_id_${meshio}})
-    if (EMSCRIPTEN AND DEFINED WebAssemblyInterface_BINARY_DIR)
-      set(target_esm_read "${read_binary}")
-      set(target_esm_write "${write_binary}")
-      foreach(target ${target_esm_read} ${target_esm_write})
-        set(exception_catching )
-        set(meshio_common_link_flags " -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s SUPPORT_LONGJMP=1")
-        get_property(link_flags TARGET ${target} PROPERTY LINK_FLAGS)
-        set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${meshio_common_link_flags} ${link_flags}")
-        itk_module_target_label(${target})
-        itk_module_target_export(${target})
-        itk_module_target_install(${target})
-        set_property(TARGET ${target}
-          PROPERTY RUNTIME_OUTPUT_DIRECTORY
-          ${WebAssemblyInterface_BINARY_DIR}/mesh-io
-          )
-      endforeach()
-    elseif (WASI AND DEFINED WebAssemblyInterface_BINARY_DIR)
-      foreach(target ${read_binary} ${write_binary})
-        itk_module_target_label(${target})
-        itk_module_target_export(${target})
-        itk_module_target_install(${target})
-        set_property(TARGET ${target}
-          PROPERTY RUNTIME_OUTPUT_DIRECTORY
-          ${WebAssemblyInterface_BINARY_DIR}/wasi-mesh-io
-          )
-      endforeach()
-    endif()
-  endforeach()
-endforeach()
-if(EMSCRIPTEN)
-  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../../MeshIOIndex.ts.in
-    ${CMAKE_CURRENT_SOURCE_DIR}/../../../MeshIOIndex.ts @ONLY)
-  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../../../MeshIOIndex.ts.in
-    ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../dist/mesh-io/index.js @ONLY)
-endif()
diff --git a/src/io/internal/pipelines/mesh/convert-mesh/itkWasmZstdMeshIO.cxx b/src/io/internal/pipelines/mesh/convert-mesh/itkWasmZstdMeshIO.cxx
deleted file mode 100644
index 32b25d5ff..000000000
--- a/src/io/internal/pipelines/mesh/convert-mesh/itkWasmZstdMeshIO.cxx
+++ /dev/null
@@ -1,158 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-
-#include "itkWasmZstdMeshIO.h"
-#include "zstd.h"
-
-namespace itk
-{
-
-WasmZstdMeshIO
-::WasmZstdMeshIO()
-{
-  this->AddSupportedWriteExtension(".iwm.cbor.zst");
-  this->AddSupportedReadExtension(".iwm.cbor.zst");
-}
-
-
-WasmZstdMeshIO
-::~WasmZstdMeshIO()
-{
-}
-
-
-bool
-WasmZstdMeshIO
-::CanReadFile(const char *filename)
-{
-  std::string fname = filename;
-
-  bool extensionFound = false;
-  std::string::size_type extensionPos = fname.rfind(".iwm");
-  if ( extensionPos != std::string::npos )
-    {
-    extensionFound = true;
-    }
-
-  if ( !extensionFound )
-    {
-    itkDebugMacro(<< "The filename extension is not recognized");
-    return false;
-    }
-
-  return true;
-}
-
-
-
-void
-WasmZstdMeshIO
-::ReadMeshInformation()
-{
-  this->SetByteOrderToLittleEndian();
-
-  const std::string path = this->GetFileName();
-
-  std::string::size_type zstdPos = path.rfind(".zst");
-  if ( ( zstdPos != std::string::npos )
-       && ( zstdPos == path.length() - 4 ) )
-  {
-    std::ifstream dataStream;
-    this->OpenFileForReading( dataStream, this->GetFileName() );
-
-    std::ostringstream ostrm;
-    ostrm << dataStream.rdbuf();
-    auto inputBinary = ostrm.str();
-
-    const size_t decompressedBufferSize = ZSTD_getFrameContentSize(inputBinary.data(), inputBinary.size());
-    std::vector<char> decompressedBinary(decompressedBufferSize);
-
-    const size_t decompressedSize = ZSTD_decompress(decompressedBinary.data(), decompressedBufferSize, inputBinary.data(), inputBinary.size());
-    decompressedBinary.resize(decompressedSize);
-
-    this->ReadCBOR(nullptr, reinterpret_cast< unsigned char *>(&(decompressedBinary.at(0))), decompressedSize);
-    return;
-  }
-
-  Superclass::ReadMeshInformation();
-}
-
-
-bool
-WasmZstdMeshIO
-::CanWriteFile(const char *name)
-{
-  std::string filename = name;
-
-  if( filename == "" )
-    {
-    return false;
-    }
-
-  bool extensionFound = false;
-  std::string::size_type iwiPos = filename.rfind(".iwm");
-  if ( iwiPos != std::string::npos )
-    {
-    extensionFound = true;
-    }
-
-  if ( !extensionFound )
-    {
-    itkDebugMacro(<< "The filename extension is not recognized");
-    return false;
-    }
-
-  return true;
-}
-
-
-void
-WasmZstdMeshIO
-::Write()
-{
-  const std::string path(this->GetFileName());
-
-  std::string::size_type cborPos = path.rfind(".zst");
-  if ( ( cborPos != std::string::npos )
-       && ( cborPos == path.length() - 4 ) )
-  {
-    unsigned char* cborBuffer;
-    size_t cborBufferSize;
-    size_t length = cbor_serialize_alloc(this->m_CBORRoot, &cborBuffer, &cborBufferSize);
-
-    const size_t compressedBufferSize = ZSTD_compressBound(cborBufferSize);
-    std::vector<char> compressedBinary(compressedBufferSize);
-
-    constexpr int compressionLevel = 3;
-    const size_t compressedSize = ZSTD_compress(compressedBinary.data(), compressedBufferSize, cborBuffer, cborBufferSize, compressionLevel);
-    free(cborBuffer);
-    cbor_decref(&(this->m_CBORRoot));
-
-    compressedBinary.resize(compressedSize);
-
-    std::ofstream outputStream;
-    this->OpenFileForWriting( outputStream, path.c_str(), true, false );
-    std::ostream_iterator<char> oIt(outputStream);
-    std::copy(compressedBinary.begin(), compressedBinary.end(), oIt);
-    return;
-  }
-
-  Superclass::Write();
-}
-
-} // end namespace itk
diff --git a/src/io/internal/pipelines/mesh/convert-mesh/itkWasmZstdMeshIO.h b/src/io/internal/pipelines/mesh/convert-mesh/itkWasmZstdMeshIO.h
deleted file mode 100644
index eaae6a470..000000000
--- a/src/io/internal/pipelines/mesh/convert-mesh/itkWasmZstdMeshIO.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#ifndef itkWasmZstdMeshIO_h
-#define itkWasmZstdMeshIO_h
-#include "WebAssemblyInterfaceExport.h"
-
-#include "itkWasmMeshIO.h"
-
-namespace itk
-{
-/** \class WasmZstdMeshIO
- *
- * \brief Read and write an itk::Mesh in a web-friendly format.
- *
- * This format is intended to facilitate data exchange in itk-wasm.
- * It reads and writes an itk-wasm Mesh object in a CBOR file on the
- * filesystem with JSON files and binary files for TypedArray's.
- * 
- * This class extends WasmMeshIO by adding support for zstandard compression.
- *
- * The file extensions used are .iwm, .iwm.cbor, and .iwm.cbor.zst.
- * 
- * \ingroup IOFilters
- * \ingroup WebAssemblyInterface
- */
-class WebAssemblyInterface_EXPORT WasmZstdMeshIO: public WasmMeshIO
-{
-public:
-  /** Standard class typedefs. */
-  typedef WasmZstdMeshIO      Self;
-  typedef WasmMeshIO          Superclass;
-  typedef SmartPointer< Self > Pointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(WasmZstdMeshIO, WasmMeshIO);
-
-  /** Determine the file type. Returns true if this MeshIO can read the
-   * file specified. */
-  bool CanReadFile(const char *) override;
-
-  /** Set the spacing and dimension information for the set filename. */
-  void ReadMeshInformation() override;
-
-  /** Determine the file type. Returns true if this MeshIO can write the
-   * file specified. */
-  bool CanWriteFile(const char *) override;
-
-  void Write() override;
-
-protected:
-  WasmZstdMeshIO();
-  ~WasmZstdMeshIO() override;
-
-private:
-  ITK_DISALLOW_COPY_AND_ASSIGN(WasmZstdMeshIO);
-};
-} // end namespace itk
-
-#endif // itkWasmZstdMeshIO_h
diff --git a/src/io/internal/pipelines/mesh/convert-mesh/read-mesh.cxx b/src/io/internal/pipelines/mesh/convert-mesh/read-mesh.cxx
deleted file mode 100644
index 503c38d43..000000000
--- a/src/io/internal/pipelines/mesh/convert-mesh/read-mesh.cxx
+++ /dev/null
@@ -1,118 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#include "itkCommonEnums.h"
-#include "itkMeshIOBase.h"
-#include "itkMesh.h"
-#include "itkOutputMeshIO.h"
-
-#ifndef MESH_IO_CLASS
-#error "MESH_IO_CLASS definition must be provided"
-#endif
-
-#if MESH_IO_CLASS == 0
-#include "itkBYUMeshIO.h"
-#elif MESH_IO_CLASS == 1
-#include "itkFreeSurferAsciiMeshIO.h"
-#elif MESH_IO_CLASS == 2
-#include "itkFreeSurferBinaryMeshIO.h"
-#elif MESH_IO_CLASS == 3
-#include "itkVTKPolyDataMeshIO.h"
-#elif MESH_IO_CLASS == 4
-#include "itkOBJMeshIO.h"
-#elif MESH_IO_CLASS == 5
-#include "itkOFFMeshIO.h"
-#elif MESH_IO_CLASS == 6
-#include "itkSTLMeshIO.h"
-#elif MESH_IO_CLASS == 7
-#include "itkSWCMeshIO.h"
-#elif MESH_IO_CLASS == 8
-#elif MESH_IO_CLASS == 9
-#include "itkWasmZstdMeshIO.h"
-#elif MESH_IO_CLASS == 21
-#elif MESH_IO_CLASS == 22
-#include "itkWasmZstdMeshIO.h"
-#else
-#error "Unsupported MESH_IO_CLASS"
-#endif
-#include "itkWasmMeshIO.h"
-
-#include "itkPipeline.h"
-#include "itkOutputMesh.h"
-
-template <typename TMeshIO>
-int readMesh(const std::string & inputFileName, itk::wasm::OutputMeshIO & outputMeshIO, bool quiet)
-{
-  using MeshIOType = TMeshIO;
-
-  auto meshIO = MeshIOType::New();
-
-  if(!meshIO->CanReadFile(inputFileName.c_str()))
-  {
-    if(!quiet)
-    {
-      std::cerr << "Could not read file: " << inputFileName << std::endl;
-    }
-    return EXIT_FAILURE;
-  }
-
-  meshIO->SetFileName(inputFileName);
-  outputMeshIO.Set(meshIO);
-
-  return EXIT_SUCCESS;
-}
-
-int main (int argc, char * argv[])
-{
-  itk::wasm::Pipeline pipeline("read-mesh", "Read an mesh file format and convert it to the itk-wasm file format", argc, argv);
-
-  std::string inputFileName;
-  pipeline.add_option("input-mesh", inputFileName, "Input mesh")->required()->check(CLI::ExistingFile);
-
-  itk::wasm::OutputMeshIO outputMeshIO;
-  pipeline.add_option("output-mesh", outputMeshIO, "Output mesh")->required();
-
-  bool quiet = false;
-  pipeline.add_flag("-q,--quiet", quiet, "Less verbose output");
-
-  ITK_WASM_PARSE(pipeline);
-
-#if MESH_IO_CLASS == 0
-  return readMesh<itk::BYUMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 1
-  return readMesh<itk::FreeSurferAsciiMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 2
-  return readMesh<itk::FreeSurferBinaryMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 3
-  return readMesh<itk::VTKPolyDataMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 4
-  return readMesh<itk::OBJMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 5
-  return readMesh<itk::OFFMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 6
-  return readMesh<itk::STLMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 7
-  return readMesh<itk::SWCMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 8
-  return readMesh<itk::WasmMeshIO>(inputFileName, outputMeshIO, quiet);
-#elif MESH_IO_CLASS == 9
-  return readMesh<itk::WasmZstdMeshIO>(inputFileName, outputMeshIO, quiet);
-#else
-#error "Unsupported MESH_IO_CLASS"
-#endif
-  return EXIT_SUCCESS;
-}
diff --git a/src/io/internal/pipelines/mesh/convert-mesh/write-mesh.cxx b/src/io/internal/pipelines/mesh/convert-mesh/write-mesh.cxx
deleted file mode 100644
index 6333403df..000000000
--- a/src/io/internal/pipelines/mesh/convert-mesh/write-mesh.cxx
+++ /dev/null
@@ -1,187 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#include "itkCommonEnums.h"
-#include "itkMeshIOBase.h"
-#include "itkMesh.h"
-#include "itkInputMeshIO.h"
-
-#ifndef MESH_IO_CLASS
-#error "MESH_IO_CLASS definition must be provided"
-#endif
-
-#if MESH_IO_CLASS == 0
-#include "itkBYUMeshIO.h"
-#elif MESH_IO_CLASS == 1
-#include "itkFreeSurferAsciiMeshIO.h"
-#elif MESH_IO_CLASS == 2
-#include "itkFreeSurferBinaryMeshIO.h"
-#elif MESH_IO_CLASS == 3
-#include "itkVTKPolyDataMeshIO.h"
-#elif MESH_IO_CLASS == 4
-#include "itkOBJMeshIO.h"
-#elif MESH_IO_CLASS == 5
-#include "itkOFFMeshIO.h"
-#elif MESH_IO_CLASS == 6
-#include "itkSTLMeshIO.h"
-#elif MESH_IO_CLASS == 7
-#include "itkSWCMeshIO.h"
-#elif MESH_IO_CLASS == 8
-#elif MESH_IO_CLASS == 9
-#include "itkWasmZstdMeshIO.h"
-#elif MESH_IO_CLASS == 21
-#elif MESH_IO_CLASS == 22
-#include "itkWasmZstdMeshIO.h"
-#else
-#error "Unsupported MESH_IO_CLASS"
-#endif
-#include "itkWasmMeshIO.h"
-
-#include "itkPipeline.h"
-#include "itkOutputMesh.h"
-#include "itkWasmMeshIOBase.h"
-#include "itkMeshIOBase.h"
-
-template <typename TMeshIO>
-int writeMesh(itk::wasm::InputMeshIO & inputMeshIO, const std::string & outputFileName, bool quiet, bool useCompression, bool binaryFileType)
-{
-  using MeshIOType = TMeshIO;
-
-  auto meshIO = MeshIOType::New();
-  meshIO->SetUseCompression(useCompression);
-  if (binaryFileType)
-  {
-    meshIO->SetFileTypeToBinary();
-  }
-  meshIO->SetByteOrderToLittleEndian();
-
-  if(!meshIO->CanWriteFile(outputFileName.c_str()))
-  {
-    if(!quiet)
-    {
-      std::cerr << "Could not write file: " << outputFileName << std::endl;
-    }
-    return EXIT_FAILURE;
-  }
-
-  meshIO->SetFileName(outputFileName);
-
-  const itk::WasmMeshIOBase * inputWasmMeshIOBase = inputMeshIO.Get();
-  const itk::MeshIOBase * inputMeshIOBase = inputWasmMeshIOBase->GetMeshIO();
-
-  const unsigned int dimension = inputMeshIOBase->GetPointDimension();
-  meshIO->SetPointDimension(dimension);
-  meshIO->SetPointComponentType(inputMeshIOBase->GetPointComponentType());
-  meshIO->SetPointPixelType(inputMeshIOBase->GetPointPixelType());
-  meshIO->SetPointPixelComponentType(inputMeshIOBase->GetPointPixelComponentType());
-  meshIO->SetNumberOfPointPixelComponents(inputMeshIOBase->GetNumberOfPointPixelComponents());
-  meshIO->SetCellComponentType(inputMeshIOBase->GetCellComponentType());
-  meshIO->SetCellPixelType(inputMeshIOBase->GetCellPixelType());
-  meshIO->SetCellPixelComponentType(inputMeshIOBase->GetCellPixelComponentType());
-  meshIO->SetNumberOfCellPixelComponents(inputMeshIOBase->GetNumberOfCellPixelComponents());
-  meshIO->SetNumberOfPoints(inputMeshIOBase->GetNumberOfPoints());
-  if (meshIO->GetNumberOfPoints())
-  {
-    meshIO->SetUpdatePoints(true);
-  }
-  meshIO->SetNumberOfPointPixels(inputMeshIOBase->GetNumberOfPointPixels());
-  if (meshIO->GetNumberOfPointPixels())
-  {
-    meshIO->SetUpdatePointData(true);
-  }
-  meshIO->SetNumberOfCells(inputMeshIOBase->GetNumberOfCells());
-  if (meshIO->GetNumberOfCells())
-  {
-    meshIO->SetUpdateCells(true);
-  }
-  meshIO->SetNumberOfCellPixels(inputMeshIOBase->GetNumberOfCellPixels());
-  if (meshIO->GetNumberOfCellPixels())
-  {
-    meshIO->SetUpdateCellData(true);
-  }
-  meshIO->SetCellBufferSize(inputMeshIOBase->GetCellBufferSize());
-
-  meshIO->WriteMeshInformation();
-
-  if (meshIO->GetNumberOfPoints())
-  {
-    meshIO->WritePoints( reinterpret_cast< void * >( const_cast< char * >(&(inputWasmMeshIOBase->GetPointsContainer()->at(0))) ));
-  }
-  if (meshIO->GetNumberOfCells())
-  {
-    meshIO->WriteCells( reinterpret_cast< void * >( const_cast< char * >(&(inputWasmMeshIOBase->GetCellsContainer()->at(0))) ));
-  }
-  if (meshIO->GetNumberOfPointPixels())
-  {
-    meshIO->WritePointData( reinterpret_cast< void * >( const_cast< char * >(&(inputWasmMeshIOBase->GetPointDataContainer()->at(0))) ));
-  }
-  if (meshIO->GetNumberOfCellPixels())
-  {
-    meshIO->WriteCellData( reinterpret_cast< void * >( const_cast< char * >(&(inputWasmMeshIOBase->GetCellDataContainer()->at(0))) ));
-  }
-
-  meshIO->Write();
-
-  return EXIT_SUCCESS;
-}
-
-int main (int argc, char * argv[])
-{
-  itk::wasm::Pipeline pipeline("write-mesh", "Write an mesh in the itk-wasm file format to another file format", argc, argv);
-
-  itk::wasm::InputMeshIO inputMeshIO;
-  pipeline.add_option("input-mesh", inputMeshIO, "Input mesh")->required();
-
-  std::string outputFileName;
-  pipeline.add_option("output-mesh", outputFileName, "Output mesh")->required();
-
-  bool quiet = false;
-  pipeline.add_flag("-q,--quiet", quiet, "Less verbose output");
-
-  bool useCompression = false;
-  pipeline.add_flag("-c,--use-compression", quiet, "Use compression in the written file, if supported");
-
-  bool binaryFileType = false;
-  pipeline.add_flag("-b,--binary-file-type", quiet, "Use a binary file type in the written file, if supported");
-
-  ITK_WASM_PARSE(pipeline);
-
-#if MESH_IO_CLASS == 0
-  return writeMesh<itk::BYUMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 1
-  return writeMesh<itk::FreeSurferAsciiMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 2
-  return writeMesh<itk::FreeSurferBinaryMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 3
-  return writeMesh<itk::VTKPolyDataMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 4
-  return writeMesh<itk::OBJMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 5
-  return writeMesh<itk::OFFMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 6
-  return writeMesh<itk::STLMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 7
-  return writeMesh<itk::SWCMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 8
-  return writeMesh<itk::WasmMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#elif MESH_IO_CLASS == 9
-  return writeMesh<itk::WasmZstdMeshIO>(inputMeshIO, outputFileName, quiet, useCompression, binaryFileType);
-#else
-#error "Unsupported MESH_IO_CLASS"
-#endif
-  return EXIT_SUCCESS;
-}
diff --git a/src/io/internal/pipelines/mesh/mesh-to-polydata/CMakeLists.txt b/src/io/internal/pipelines/mesh/mesh-to-polydata/CMakeLists.txt
deleted file mode 100644
index b63cc3fef..000000000
--- a/src/io/internal/pipelines/mesh/mesh-to-polydata/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(mesh-to-polydata)
-
-set(CMAKE_CXX_STANDARD 17)
-
-find_package(ITK REQUIRED
-  COMPONENTS
-    WebAssemblyInterface
-    MeshToPolyData
-    )
-include(${ITK_USE_FILE})
-
-add_executable(mesh-to-polydata mesh-to-polydata.cxx)
-target_link_libraries(mesh-to-polydata PUBLIC ${ITK_LIBRARIES})
-
-add_executable(polydata-to-mesh polydata-to-mesh.cxx)
-target_link_libraries(polydata-to-mesh PUBLIC ${ITK_LIBRARIES})
-
-if (EMSCRIPTEN AND DEFINED WebAssemblyInterface_BINARY_DIR)
-  foreach(target mesh-to-polydata polydata-to-mesh)
-    itk_module_target_label(${target})
-    itk_module_target_export(${target})
-    itk_module_target_install(${target})
-    set_property(TARGET ${target}
-      PROPERTY RUNTIME_OUTPUT_DIRECTORY
-      ${WebAssemblyInterface_BINARY_DIR}/mesh-io
-      )
-  endforeach()
-endif()
-if (WASI AND DEFINED WebAssemblyInterface_BINARY_DIR)
-  foreach(target mesh-to-polydata polydata-to-mesh)
-    itk_module_target_label(${target})
-    itk_module_target_export(${target})
-    itk_module_target_install(${target})
-    set_property(TARGET ${target}
-      PROPERTY RUNTIME_OUTPUT_DIRECTORY
-      ${WebAssemblyInterface_BINARY_DIR}/wasi-mesh-io
-      )
-  endforeach()
-endif()
diff --git a/src/io/internal/pipelines/mesh/mesh-to-polydata/mesh-to-polydata.cxx b/src/io/internal/pipelines/mesh/mesh-to-polydata/mesh-to-polydata.cxx
deleted file mode 100644
index dc75fe186..000000000
--- a/src/io/internal/pipelines/mesh/mesh-to-polydata/mesh-to-polydata.cxx
+++ /dev/null
@@ -1,73 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#include "itkMesh.h"
-#include "itkPolyData.h"
-#include "itkInputMesh.h"
-#include "itkOutputPolyData.h"
-#include "itkPipeline.h"
-#include "itkSupportInputMeshTypes.h"
-#include "itkWasmMeshIOFactory.h"
-#include "itkMeshToPolyDataFilter.h"
-#include "itkVector.h"
-
-template<typename TMesh>
-class PipelineFunctor
-{
-public:
-  int operator()(itk::wasm::Pipeline & pipeline)
-  {
-    using MeshType = TMesh;
-
-    using InputMeshType = itk::wasm::InputMesh<MeshType>;
-    InputMeshType inputMesh;
-    pipeline.add_option("input-mesh", inputMesh, "Input mesh")->required()->type_name("INPUT_MESH");
-
-    using PolyDataType = itk::PolyData<typename MeshType::PixelType>;
-    using OutputPolyDataType = itk::wasm::OutputPolyData<PolyDataType>;
-    OutputPolyDataType outputPolyData;
-    pipeline.add_option("output-polydata", outputPolyData, "Output polydata")->required()->type_name("OUTPUT_POLYDATA");
-
-    ITK_WASM_PARSE(pipeline);
-
-    using MeshToPolyDataFilterType = itk::MeshToPolyDataFilter<MeshType>;
-    auto meshToPolyDataFilter = MeshToPolyDataFilterType::New();
-    meshToPolyDataFilter->SetInput(inputMesh.Get());
-    meshToPolyDataFilter->Update();
-
-    outputPolyData.Set(meshToPolyDataFilter->GetOutput());
-
-    return EXIT_SUCCESS;
-  }
-};
-
-int main (int argc, char * argv[])
-{
-  itk::wasm::Pipeline pipeline("mesh-to-polydata", "Convert an itk::Mesh to an itk::PolyData", argc, argv);
-
-  itk::WasmMeshIOFactory::RegisterOneFactory();
-
-  return itk::wasm::SupportInputMeshTypes<PipelineFunctor,
-   uint8_t,
-   int8_t,
-   float,
-   double,
-   itk::Vector<uint8_t, 3>,
-   itk::Vector<float, 3>
-   >
-  ::Dimensions<2U,3U>("input-mesh", pipeline);
-}
diff --git a/src/io/internal/pipelines/mesh/mesh-to-polydata/polydata-to-mesh.cxx b/src/io/internal/pipelines/mesh/mesh-to-polydata/polydata-to-mesh.cxx
deleted file mode 100644
index 0f003760f..000000000
--- a/src/io/internal/pipelines/mesh/mesh-to-polydata/polydata-to-mesh.cxx
+++ /dev/null
@@ -1,65 +0,0 @@
-/*=========================================================================
- *
- *  Copyright NumFOCUS
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *         https://www.apache.org/licenses/LICENSE-2.0.txt
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *=========================================================================*/
-#include "itkMesh.h"
-#include "itkPolyData.h"
-#include "itkInputPolyData.h"
-#include "itkOutputMesh.h"
-#include "itkPipeline.h"
-#include "itkSupportInputPolyDataTypes.h"
-#include "itkWasmMeshIOFactory.h"
-#include "itkPolyDataToMeshFilter.h"
-
-template<typename TPolyData>
-class PipelineFunctor
-{
-public:
-  int operator()(itk::wasm::Pipeline & pipeline)
-  {
-    using PolyDataType = TPolyData;
-
-    using InputPolyDataType = itk::wasm::InputPolyData<PolyDataType>;
-    InputPolyDataType inputPolyData;
-    pipeline.add_option("input-polydata", inputPolyData, "Input polydata")->required()->type_name("INPUT_POLYDATA");
-
-    using MeshType = itk::Mesh<typename PolyDataType::PixelType, 3>;
-    using OutputMeshType = itk::wasm::OutputMesh<MeshType>;
-    OutputMeshType outputMesh;
-    pipeline.add_option("output-mesh", outputMesh, "Output mesh")->required()->type_name("OUTPUT_MESH");
-
-    ITK_WASM_PARSE(pipeline);
-
-    using PolyDataToMeshFilterType = itk::PolyDataToMeshFilter<PolyDataType>;
-    auto polyDataToMeshFilter = PolyDataToMeshFilterType::New();
-    polyDataToMeshFilter->SetInput(inputPolyData.Get());
-    polyDataToMeshFilter->Update();
-
-    outputMesh.Set(polyDataToMeshFilter->GetOutput());
-
-    return EXIT_SUCCESS;
-  }
-};
-
-int main (int argc, char * argv[])
-{
-  itk::wasm::Pipeline pipeline("polydata-to-mesh", "Convert an itk::PolyData to an itk::Mesh", argc, argv);
-
-  itk::WasmMeshIOFactory::RegisterOneFactory();
-
-  return itk::wasm::SupportInputPolyDataTypes<PipelineFunctor>
-  ::PixelTypes<uint8_t,int8_t,float,double>("input-polydata", pipeline);
-}
diff --git a/src/io/meshToPolyData.ts b/src/io/meshToPolyData.ts
deleted file mode 100644
index 0db58ace1..000000000
--- a/src/io/meshToPolyData.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-import Mesh from '../core/interface-types/mesh.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PolyData from '../core/interface-types/poly-data.js'
-import meshTransferables from '../core/internal/meshTransferables.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import MeshToPolyDataPipelineResult from '../core/web-workers/mesh-to-poly-data-pipeline-result.js'
-import config from '../itkConfig.js'
-import getTransferables from '../core/get-transferables.js'
-
-async function meshToPolyData (webWorker: Worker | null, mesh: Mesh): Promise<{ polyData: PolyData, webWorker: Worker }> {
-  let worker = webWorker
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(worker, null)
-  worker = usedWorker
-
-  const args = ['0', '0', '--memory-io']
-  const outputs = [
-    { type: InterfaceTypes.PolyData }
-  ]
-  const inputs = [
-    { type: InterfaceTypes.Mesh, data: mesh }
-  ] as PipelineInput[]
-
-  const transferables = meshTransferables(mesh)
-
-  const result: MeshToPolyDataPipelineResult = await workerProxy.meshToPolyData(
-    config,
-    args,
-    outputs,
-    Comlink.transfer(inputs, getTransferables(transferables))
-  )
-  return { polyData: result.outputs[0].data as PolyData, webWorker: worker }
-}
-
-export default meshToPolyData
diff --git a/src/io/meshToPolyDataNode.ts b/src/io/meshToPolyDataNode.ts
deleted file mode 100644
index 5a627a51e..000000000
--- a/src/io/meshToPolyDataNode.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import path from 'path'
-
-import Mesh from '../core/interface-types/mesh.js'
-import PolyData from '../core/interface-types/poly-data.js'
-import findLocalMeshIOPath from './internal/findLocalMeshIOPath.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import loadEmscriptenModule from './../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from '../pipeline/internal/runPipelineEmscripten.js'
-import PipelineEmscriptenModule from '../pipeline/PipelineEmscriptenModule.js'
-
-async function meshToPolyDataNode (mesh: Mesh): Promise<PolyData> {
-  const meshIOsPath = findLocalMeshIOPath()
-
-  const args = ['0', '0', '--memory-io']
-  const desiredOutputs = [
-    { type: InterfaceTypes.PolyData }
-  ]
-  const inputs = [
-    { type: InterfaceTypes.Mesh, data: mesh }
-  ] as PipelineInput[]
-
-  const modulePath = path.join(meshIOsPath, 'mesh-to-polydata.js')
-  const emModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-  const { outputs } = runPipelineEmscripten(emModule, args, desiredOutputs, inputs)
-  return outputs[0].data as PolyData
-}
-
-export default meshToPolyDataNode
diff --git a/src/io/node/index.ts b/src/io/node/index.ts
deleted file mode 100644
index cccff4df1..000000000
--- a/src/io/node/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// Node IO functions
-
-export { default as getFileExtension } from './../getFileExtension.js'
-export { default as extensionToImageIO } from './../extensionToImageIO.js'
-export { default as extensionToMeshIO } from './../extensionToMeshIO.js'
-
-export { default as readLocalFile } from './../readLocalFile.js'
-
-export { default as readImageLocalFile } from './../readImageLocalFile.js'
-export { default as readMeshLocalFile } from './../readMeshLocalFile.js'
-
-export { default as readDICOMTagsLocalFile } from './../deprecated/readDICOMTagsLocalFile.js'
-export { default as readImageLocalDICOMFileSeries } from './../deprecated/readImageLocalDICOMFileSeries.js'
-
-export { default as WriteImageOptions } from './../WriteImageOptions.js'
-export { default as writeImageLocalFile } from './../writeImageLocalFile.js'
-export { default as WriteMeshOptions } from './../WriteMeshOptions.js'
-export { default as writeMeshLocalFile } from './../writeMeshLocalFile.js'
-export { default as writeLocalFile } from './../writeLocalFile.js'
-
-export { default as meshToPolyDataNode } from './../meshToPolyDataNode.js'
-export { default as polyDataToMeshNode } from './../polyDataToMeshNode.js'
diff --git a/src/io/polyDataToMesh.ts b/src/io/polyDataToMesh.ts
deleted file mode 100644
index 8c8fe55a4..000000000
--- a/src/io/polyDataToMesh.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-import PolyDataToMeshPipelineResult from '../core/web-workers/poly-data-to-mesh-pipeline-result.js'
-import Mesh from '../core/interface-types/mesh.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PolyData from '../core/interface-types/poly-data.js'
-import polyDataTransferables from '../core/internal/polyDataTransferables.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import config from '../itkConfig.js'
-import getTransferables from '../core/get-transferables.js'
-
-async function polyDataToMesh (webWorker: Worker | null, polyData: PolyData): Promise<{ mesh: Mesh, webWorker: Worker }> {
-  let worker = webWorker
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(worker, null)
-  worker = usedWorker
-
-  const args = ['0', '0', '--memory-io']
-  const outputs = [
-    { type: InterfaceTypes.Mesh }
-  ]
-  const inputs = [
-    { type: InterfaceTypes.PolyData, data: polyData }
-  ] as PipelineInput[]
-
-  const transferables = polyDataTransferables(polyData)
-
-  const result: PolyDataToMeshPipelineResult = await workerProxy.polyDataToMesh(
-    config,
-    args,
-    outputs,
-    Comlink.transfer(inputs, getTransferables(transferables))
-  )
-  return { mesh: result.outputs[0].data as Mesh, webWorker: worker }
-}
-
-export default polyDataToMesh
diff --git a/src/io/readArrayBuffer.ts b/src/io/readArrayBuffer.ts
deleted file mode 100644
index 08b50f773..000000000
--- a/src/io/readArrayBuffer.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import readImageArrayBuffer from './readImageArrayBuffer.js'
-import readMeshArrayBuffer from './readMeshArrayBuffer.js'
-
-import getFileExtension from './getFileExtension.js'
-import extensionToMeshIO from './extensionToMeshIO.js'
-import mimeToMeshIO from './internal/MimeToMeshIO.js'
-
-import ReadImageResult from './ReadImageResult.js'
-import ReadMeshResult from './ReadMeshResult.js'
-
-async function readArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, mimeType: string): Promise<ReadImageResult | ReadMeshResult > {
-  const extension = getFileExtension(fileName)
-  const isMesh = !!extensionToMeshIO.has(extension) || !!mimeToMeshIO.has(mimeType)
-  if (isMesh) {
-    return await readMeshArrayBuffer(webWorker, arrayBuffer, fileName, mimeType)
-      .catch(async function () {
-        if (webWorker !== null) {
-          webWorker.terminate()
-        }
-        return await readImageArrayBuffer(null, arrayBuffer, fileName, mimeType)
-      })
-  } else {
-    return await readImageArrayBuffer(webWorker, arrayBuffer, fileName, mimeType)
-  }
-}
-
-export default readArrayBuffer
diff --git a/src/io/readBlob.ts b/src/io/readBlob.ts
deleted file mode 100644
index 228c529e8..000000000
--- a/src/io/readBlob.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import readImageBlob from './readImageBlob.js'
-import readMeshBlob from './readMeshBlob.js'
-
-import getFileExtension from './getFileExtension.js'
-import extensionToMeshIO from './extensionToMeshIO.js'
-import mimeToMeshIO from './internal/MimeToMeshIO.js'
-
-import ReadImageResult from './ReadImageResult.js'
-import ReadMeshResult from './ReadMeshResult.js'
-
-async function readBlob (webWorker: Worker | null, blob: Blob, fileName: string, mimeType: string): Promise<ReadImageResult | ReadMeshResult > {
-  const extension = getFileExtension(fileName)
-  const isMesh = !!extensionToMeshIO.has(extension) || !!mimeToMeshIO.has(mimeType)
-  if (isMesh) {
-    return await readMeshBlob(webWorker, blob, fileName, mimeType)
-      .catch(async function () {
-        if (webWorker !== null) {
-          webWorker.terminate()
-        }
-        return await readImageBlob(null, blob, fileName, mimeType)
-      })
-  } else {
-    return await readImageBlob(webWorker, blob, fileName, mimeType)
-  }
-}
-
-export default readBlob
diff --git a/src/io/readFile.ts b/src/io/readFile.ts
deleted file mode 100644
index 731d50fba..000000000
--- a/src/io/readFile.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import readImageFile from './readImageFile.js'
-import readMeshFile from './readMeshFile.js'
-
-import getFileExtension from './getFileExtension.js'
-import extensionToMeshIO from './extensionToMeshIO.js'
-
-import ReadImageResult from './ReadImageResult.js'
-import ReadMeshResult from './ReadMeshResult.js'
-
-async function readFile (webWorker: Worker | null, file: File): Promise<ReadImageResult | ReadMeshResult > {
-  const extension = getFileExtension(file.name)
-  const isMesh = extensionToMeshIO.has(extension)
-  if (isMesh) {
-    try {
-      const result = await readMeshFile(webWorker, file)
-      return result
-    } catch (unused) {
-      if (webWorker != null) {
-        webWorker.terminate()
-      }
-      return await readImageFile(null, file)
-    }
-  } else {
-    return await readImageFile(webWorker, file)
-  }
-}
-
-export default readFile
diff --git a/src/io/readImageArrayBuffer.ts b/src/io/readImageArrayBuffer.ts
deleted file mode 100644
index 861a1e8a3..000000000
--- a/src/io/readImageArrayBuffer.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-import getTransferables from '../core/get-transferables.js'
-import ReadImagePipelineResult from '../core/web-workers/read-image-pipeline-result.js'
-import Image from '../core/interface-types/image.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import castImage from '../core/castImage.js'
-
-import config from '../itkConfig.js'
-
-import ReadImageResult from './ReadImageResult.js'
-import ReadImageArrayBufferOptions from './ReadImageArrayBufferOptions.js'
-
-async function readImageArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, options?: ReadImageArrayBufferOptions | string): Promise<ReadImageResult> {
-  let worker = webWorker
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(worker, null)
-  worker = usedWorker
-
-  const filePath = `./${fileName}`
-  const args = [filePath, '0', '--memory-io', '--quiet']
-  const outputs = [
-    { type: InterfaceTypes.Image }
-  ]
-  const inputs = [
-    { type: InterfaceTypes.BinaryFile, data: { path: filePath, data: new Uint8Array(arrayBuffer) } }
-  ] as PipelineInput[]
-
-  const transferables: ArrayBuffer[] = [arrayBuffer]
-  let mimeType
-  if (typeof options === 'string') {
-    // backwards compatibility
-    mimeType = options
-  } else if (typeof options === 'object') {
-    if (typeof options.mimeType === 'string') {
-      mimeType = options.mimeType
-    }
-  }
-  const mimeTypeString = mimeType?.toString() ?? ''
-  const result: ReadImagePipelineResult = await workerProxy.readImage(
-    config,
-    mimeTypeString,
-    fileName,
-    args,
-    outputs,
-    Comlink.transfer(inputs, getTransferables(transferables))
-  )
-  let image = result.outputs[0].data as Image
-  if (typeof options === 'object' && (typeof options.componentType !== 'undefined' || typeof options.pixelType !== 'undefined')) {
-    image = castImage(image, options)
-  }
-
-  return { image, webWorker: worker }
-}
-
-export default readImageArrayBuffer
diff --git a/src/io/readImageBlob.ts b/src/io/readImageBlob.ts
deleted file mode 100644
index 267a355d3..000000000
--- a/src/io/readImageBlob.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import readImageArrayBuffer from './readImageArrayBuffer.js'
-import ReadImageResult from './ReadImageResult.js'
-import ReadImageArrayBufferOptions from './ReadImageArrayBufferOptions.js'
-
-async function readImageBlob (webWorker: Worker | null, blob: Blob, fileName: string, options?: ReadImageArrayBufferOptions | string): Promise<ReadImageResult> {
-  const arrayBuffer = await blob.arrayBuffer()
-  return await readImageArrayBuffer(webWorker, arrayBuffer, fileName, options)
-}
-
-export default readImageBlob
diff --git a/src/io/readImageFile.ts b/src/io/readImageFile.ts
deleted file mode 100644
index 881376cb4..000000000
--- a/src/io/readImageFile.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import readImageArrayBuffer from './readImageArrayBuffer.js'
-import ReadImageResult from './ReadImageResult.js'
-import CastImageOptions from '../core/CastImageOptions.js'
-import ReadImageArrayBufferOptions from './ReadImageArrayBufferOptions.js'
-
-async function readImageFile (webWorker: Worker | null, file: File, options?: CastImageOptions): Promise<ReadImageResult> {
-  const arrayBuffer = await file.arrayBuffer()
-  const optionsToPass: ReadImageArrayBufferOptions = typeof options === 'undefined' ? {} : { ...options }
-  optionsToPass.mimeType = file.type
-  return await readImageArrayBuffer(webWorker, arrayBuffer, file.name, optionsToPass)
-}
-
-export default readImageFile
diff --git a/src/io/readImageFileSeries.ts b/src/io/readImageFileSeries.ts
deleted file mode 100644
index 1068b8a4c..000000000
--- a/src/io/readImageFileSeries.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import stackImages from '../core/stackImages.js'
-import readImageArrayBuffer from './readImageArrayBuffer.js'
-import WorkerPool from '../core/WorkerPool.js'
-import castImage from '../core/castImage.js'
-
-import ReadImageFileSeriesResult from './ReadImageFileSeriesResult.js'
-import ReadImageFileSeriesOptions from './ReadImageFileSeriesOptions.js'
-
-const numberOfWorkers = typeof globalThis.navigator?.hardwareConcurrency === 'number' ? globalThis.navigator.hardwareConcurrency : 6
-const workerPool = new WorkerPool(numberOfWorkers, readImageArrayBuffer)
-
-async function readImageFileSeries (
-  fileList: File[] | FileList,
-  options?: ReadImageFileSeriesOptions | number,
-  zOriginBackwardsCompatibility?: number,
-  sortedSeriesBackwardsCompatibility?: boolean
-): Promise<ReadImageFileSeriesResult> {
-  let zSpacing = 1.0
-  let zOrigin = 0.0
-  let sortedSeries = false
-  if (typeof options === 'number') {
-    // Backwards compatibility
-    zSpacing = options
-  }
-  if (typeof zOriginBackwardsCompatibility !== 'undefined') {
-    zOrigin = zOriginBackwardsCompatibility
-  }
-  if (typeof sortedSeriesBackwardsCompatibility !== 'undefined') {
-    sortedSeries = sortedSeriesBackwardsCompatibility
-  }
-  if (typeof options === 'object') {
-    if (typeof options.zSpacing !== 'undefined') {
-      zSpacing = options.zSpacing
-    }
-    if (typeof options.zOrigin !== 'undefined') {
-      zOrigin = options.zOrigin
-    }
-    if (typeof options.sortedSeries !== 'undefined') {
-      sortedSeries = options.sortedSeries
-    }
-  }
-  const fetchFileDescriptions = Array.from(fileList, async function (file) {
-    return await file.arrayBuffer().then(function (
-      arrayBuffer
-    ) {
-      const fileDescription = {
-        name: file.name,
-        type: file.type,
-        data: arrayBuffer
-      }
-      return fileDescription
-    })
-  })
-
-  const fileDescriptions = await Promise.all(fetchFileDescriptions)
-  if (!sortedSeries) {
-    fileDescriptions.sort((a, b) => {
-      if (a.name < b.name) {
-        return -1
-      }
-      if (a.name > b.name) {
-        return 1
-      }
-      return 0
-    })
-  }
-  const taskArgsArray = []
-  for (let index = 0; index < fileDescriptions.length; index++) {
-    taskArgsArray.push([fileDescriptions[index].data, fileDescriptions[index].name])
-  }
-  const results = await workerPool.runTasks(taskArgsArray).promise
-  const images = results.map((result) => {
-    const image = result.image
-    image.imageType.dimension = 3
-    image.size.push(1)
-    image.spacing.push(zSpacing)
-    image.origin.push(zOrigin)
-    image.direction = new Float64Array(9)
-    image.direction.fill(0.0)
-    image.direction[0] = 1.0
-    image.direction[4] = 1.0
-    image.direction[8] = 1.0
-    return image
-  })
-  let stacked = stackImages(images)
-  if (typeof options === 'object' && (typeof options.componentType !== 'undefined' || typeof options.pixelType !== 'undefined')) {
-    stacked = castImage(stacked, options)
-  }
-  return { image: stacked, webWorkerPool: workerPool }
-}
-
-export default readImageFileSeries
diff --git a/src/io/readImageLocalFile.ts b/src/io/readImageLocalFile.ts
deleted file mode 100644
index 50f405cd4..000000000
--- a/src/io/readImageLocalFile.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import path from 'path'
-import mime from 'mime-types'
-
-import mimeToIO from './internal/MimeToImageIO.js'
-import getFileExtension from './getFileExtension.js'
-import extensionToIO from './extensionToImageIO.js'
-import ImageIOIndex from './internal/ImageIOIndex.js'
-
-import Image from '../core/interface-types/image.js'
-
-import loadEmscriptenModule from '../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from '../pipeline/internal/runPipelineEmscripten.js'
-import PipelineEmscriptenModule from '../pipeline/PipelineEmscriptenModule.js'
-import findLocalImageIOPath from './internal/findLocalImageIOPath.js'
-import runPipelineNode from '../pipeline/runPipelineNode.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import CastImageOptions from '../core/CastImageOptions.js'
-import castImage from '../core/castImage.js'
-
-/**
- * Read an image from a file on the local filesystem in Node.js.
- *
- * @param: filePath path to the file on the local filesystem.
- * @param {CastImageOptions} options - specify the componentType and/or pixelType of the output
- */
-async function readImageLocalFile (filePath: string, options?: CastImageOptions): Promise<Image> {
-  const imageIOsPath = findLocalImageIOPath()
-  const absoluteFilePath = path.resolve(filePath)
-  const mimeType = mime.lookup(absoluteFilePath)
-  const extension = getFileExtension(absoluteFilePath)
-
-  const args = [absoluteFilePath, '0', '--memory-io', '--quiet']
-  const desiredOutputs = [
-    { type: InterfaceTypes.Image }
-  ]
-  const inputs = [] as PipelineInput[]
-
-  let io = null
-  if (mimeType !== false && mimeToIO.has(mimeType)) {
-    io = mimeToIO.get(mimeType)
-  } else if (extensionToIO.has(extension)) {
-    io = extensionToIO.get(extension)
-  } else {
-    for (let idx = 0; idx < ImageIOIndex.length; ++idx) {
-      const modulePath = path.join(imageIOsPath, ImageIOIndex[idx] + '-read-image.js')
-      const readImageModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-      const mountedFilePath = readImageModule.mountContainingDir(absoluteFilePath)
-      const { returnValue, outputs } = runPipelineEmscripten(readImageModule, args, desiredOutputs, inputs)
-      readImageModule.unmountContainingDir(mountedFilePath)
-      if (returnValue === 0) {
-        return outputs[0].data as Image
-      }
-    }
-  }
-  if (io === null) {
-    throw Error('Could not find IO for: ' + absoluteFilePath)
-  }
-
-  const modulePath = path.join(imageIOsPath, io as string + '-read-image.js')
-  const mountDirs = new Set([path.dirname(absoluteFilePath)])
-  const { outputs } = await runPipelineNode(modulePath, args, desiredOutputs, inputs, mountDirs)
-
-  let result = outputs[0].data as Image
-
-  if (typeof options !== 'undefined') {
-    result = castImage(result, options)
-  }
-
-  return result
-}
-
-export default readImageLocalFile
diff --git a/src/io/readLocalFile.ts b/src/io/readLocalFile.ts
deleted file mode 100644
index 711780489..000000000
--- a/src/io/readLocalFile.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import path from 'path'
-
-import getFileExtension from './getFileExtension.js'
-import extensionToMeshIO from './extensionToMeshIO.js'
-
-import readImageLocalFile from './readImageLocalFile.js'
-import readMeshLocalFile from './readMeshLocalFile.js'
-
-import Image from '../core/interface-types/image.js'
-import Mesh from '../core/interface-types/mesh.js'
-
-/**
- * Read an image or mesh from a file on the local filesystem in Node.js.
- *
- * @param: filePath path to the file on the local filesystem.
- */
-async function readLocalFile (filePath: string): Promise<Image | Mesh> {
-  const absoluteFilePath = path.resolve(filePath)
-  const extension = getFileExtension(absoluteFilePath)
-
-  const isMesh = extensionToMeshIO.has(extension)
-  if (isMesh) {
-    try {
-      const mesh = await readMeshLocalFile(filePath)
-      return mesh
-    } catch (err) {
-      // Was a .vtk image file? Continue to read as an image.
-      const image = await readImageLocalFile(filePath)
-      return image
-    }
-  } else {
-    const image = await readImageLocalFile(filePath)
-    return image
-  }
-}
-
-export default readLocalFile
diff --git a/src/io/readMeshArrayBuffer.ts b/src/io/readMeshArrayBuffer.ts
deleted file mode 100644
index dfe1148e0..000000000
--- a/src/io/readMeshArrayBuffer.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-import getTransferables from '../core/get-transferables.js'
-import Mesh from '../core/interface-types/mesh.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import ReadMeshPipelineResult from '../core/web-workers/read-mesh-pipeline-result.js'
-
-import config from '../itkConfig.js'
-
-import ReadMeshResult from './ReadMeshResult.js'
-
-async function readMeshArrayBuffer (webWorker: Worker | null, arrayBuffer: ArrayBuffer, fileName: string, mimeType: string): Promise<ReadMeshResult> {
-  let worker = webWorker
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(worker, null)
-  worker = usedWorker
-
-  const filePath = `./${fileName}`
-  const args = [filePath, '0', '--memory-io', '--quiet']
-  const outputs = [
-    { type: InterfaceTypes.Mesh }
-  ]
-  const inputs = [
-    { type: InterfaceTypes.BinaryFile, data: { path: filePath, data: new Uint8Array(arrayBuffer) } }
-  ] as PipelineInput[]
-
-  const transferables: ArrayBuffer[] = [arrayBuffer]
-
-  const result: ReadMeshPipelineResult = await workerProxy.readMesh(
-    config,
-    mimeType,
-    fileName,
-    args,
-    outputs,
-    Comlink.transfer(inputs, getTransferables(transferables))
-  )
-  return { mesh: result.outputs[0].data as Mesh, webWorker: worker }
-}
-
-export default readMeshArrayBuffer
diff --git a/src/io/readMeshBlob.ts b/src/io/readMeshBlob.ts
deleted file mode 100644
index 06a052063..000000000
--- a/src/io/readMeshBlob.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import readMeshArrayBuffer from './readMeshArrayBuffer.js'
-import ReadMeshResult from './ReadMeshResult.js'
-
-async function readMeshBlob (webWorker: Worker | null, blob: Blob, fileName: string, mimeType: string): Promise<ReadMeshResult> {
-  const arrayBuffer = await blob.arrayBuffer()
-  return await readMeshArrayBuffer(webWorker, arrayBuffer, fileName, mimeType)
-}
-
-export default readMeshBlob
diff --git a/src/io/readMeshFile.ts b/src/io/readMeshFile.ts
deleted file mode 100644
index d7c3855dc..000000000
--- a/src/io/readMeshFile.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import readMeshArrayBuffer from './readMeshArrayBuffer.js'
-import ReadMeshResult from './ReadMeshResult.js'
-
-async function readMeshFile (webWorker: Worker | null, file: File): Promise<ReadMeshResult> {
-  const arrayBuffer = await file.arrayBuffer()
-  return await readMeshArrayBuffer(webWorker, arrayBuffer, file.name, file.type)
-}
-
-export default readMeshFile
diff --git a/src/io/readMeshLocalFile.ts b/src/io/readMeshLocalFile.ts
deleted file mode 100644
index e5f008001..000000000
--- a/src/io/readMeshLocalFile.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import path from 'path'
-import mime from 'mime-types'
-
-import mimeToIO from './internal/MimeToMeshIO.js'
-import getFileExtension from './getFileExtension.js'
-import extensionToIO from './extensionToMeshIO.js'
-import MeshIOIndex from './internal/MeshIOIndex.js'
-
-import Mesh from '../core/interface-types/mesh.js'
-
-import loadEmscriptenModule from './../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from '../pipeline/internal/runPipelineEmscripten.js'
-import PipelineEmscriptenModule from '../pipeline/PipelineEmscriptenModule.js'
-import findLocalMeshIOPath from './internal/findLocalMeshIOPath.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-
-/**
- * Read a mesh from a file on the local filesystem in Node.js.
- *
- * @param: filePath path to the file on the local filesystem.
- */
-async function readMeshLocalFile (filePath: string): Promise<Mesh> {
-  const meshIOsPath = findLocalMeshIOPath()
-  const absoluteFilePath = path.resolve(filePath)
-  const mimeType = mime.lookup(absoluteFilePath)
-  const extension = getFileExtension(absoluteFilePath)
-
-  const args = [absoluteFilePath, '0', '--memory-io', '--quiet']
-  const desiredOutputs = [
-    { type: InterfaceTypes.Mesh }
-  ]
-  const inputs = [] as PipelineInput[]
-
-  let io = null
-  if (mimeToIO.has(mimeType)) {
-    io = mimeToIO.get(mimeType)
-  } else if (extensionToIO.has(extension)) {
-    io = extensionToIO.get(extension)
-  } else {
-    for (let idx = 0; idx < MeshIOIndex.length; ++idx) {
-      const modulePath = path.join(meshIOsPath, MeshIOIndex[idx] + '-read-mesh.js')
-      const readMeshModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-      const mountedFilePath = readMeshModule.mountContainingDir(absoluteFilePath)
-      const { returnValue, outputs } = runPipelineEmscripten(readMeshModule, args, desiredOutputs, inputs)
-      readMeshModule.unmountContainingDir(mountedFilePath)
-      if (returnValue === 0) {
-        return outputs[0].data as Mesh
-      }
-    }
-  }
-  if (io === null) {
-    throw Error('Could not find IO for: ' + absoluteFilePath)
-  }
-
-  const modulePath = path.join(meshIOsPath, io as string + '-read-mesh.js')
-  const readMeshModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-  const mountedFilePath = readMeshModule.mountContainingDir(absoluteFilePath)
-  const { outputs } = runPipelineEmscripten(readMeshModule, args, desiredOutputs, inputs)
-  readMeshModule.unmountContainingDir(mountedFilePath)
-  return outputs[0].data as Mesh
-}
-
-export default readMeshLocalFile
diff --git a/src/io/writeArrayBuffer.ts b/src/io/writeArrayBuffer.ts
deleted file mode 100644
index 3b616896e..000000000
--- a/src/io/writeArrayBuffer.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import writeImageArrayBuffer from './writeImageArrayBuffer.js'
-import writeMeshArrayBuffer from './writeMeshArrayBuffer.js'
-
-import getFileExtension from './getFileExtension.js'
-import extensionToMeshIO from './extensionToMeshIO.js'
-import mimeToMeshIO from './internal/MimeToMeshIO.js'
-
-import Image from '../core/interface-types/image.js'
-import Mesh from '../core/interface-types/mesh.js'
-
-import WriteArrayBufferResult from './WriteArrayBufferResult.js'
-
-async function writeArrayBuffer (webWorker: Worker | null, imageOrMesh: Image | Mesh, fileName: string, mimeType: string = '', useCompression: boolean = false): Promise<WriteArrayBufferResult> {
-  if (typeof imageOrMesh === 'boolean') {
-    throw new Error('useCompression is now the argument position in itk-wasm')
-  }
-
-  const extension = getFileExtension(fileName)
-  const isMesh = !!extensionToMeshIO.has(extension) || !!mimeToMeshIO.has(mimeType)
-  if (isMesh) {
-    return await writeMeshArrayBuffer(webWorker, imageOrMesh as Mesh, fileName, mimeType, { useCompression })
-      .catch(async function () {
-        if (webWorker != null) {
-          webWorker.terminate()
-        }
-        return await writeImageArrayBuffer(null, imageOrMesh as Image, fileName, mimeType, useCompression)
-      })
-  } else {
-    return await writeImageArrayBuffer(webWorker, imageOrMesh as Image, fileName, mimeType, useCompression)
-  }
-}
-
-export default writeArrayBuffer
diff --git a/src/io/writeImageArrayBuffer.ts b/src/io/writeImageArrayBuffer.ts
deleted file mode 100644
index 3ba832052..000000000
--- a/src/io/writeImageArrayBuffer.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-
-import Image from '../core/interface-types/image.js'
-
-import config from '../itkConfig.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import PipelineOutput from '../pipeline/PipelineOutput.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import getTransferables from '../core/get-transferables.js'
-import castImage from '../core/castImage.js'
-import WriteImagePipelineResult from '../core/web-workers/write-image-pipeline-result.js'
-
-import WriteImageOptions from './WriteImageOptions.js'
-import WriteArrayBufferResult from './WriteArrayBufferResult.js'
-import imageTransferables from '../core/internal/imageTransferables.js'
-
-async function writeImageArrayBuffer (webWorker: Worker | null, image: Image, fileName: string, options?: WriteImageOptions | string, useCompressionBackwardsCompatibility?: boolean
-): Promise<WriteArrayBufferResult> {
-  if (typeof image === 'boolean') {
-    throw new Error('useCompression is now at the last argument position in itk-wasm')
-  }
-
-  let mimeType = ''
-  if (typeof options === 'string') {
-    mimeType = options
-  }
-  let useCompression = false
-  if (typeof useCompressionBackwardsCompatibility === 'boolean') {
-    useCompression = useCompressionBackwardsCompatibility
-  }
-  if (typeof options === 'object' && typeof options.useCompression !== 'undefined') {
-    useCompression = options.useCompression
-  }
-
-  let worker = webWorker
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(worker, null)
-  worker = usedWorker
-
-  const filePath = `./${fileName}`
-  const args = ['0', filePath, '--memory-io', '--quiet']
-  if (useCompression) {
-    args.push('--use-compression')
-  }
-  const outputs = [
-    { data: { path: filePath }, type: InterfaceTypes.BinaryFile }
-  ] as PipelineOutput[]
-  let inputImage = image
-  if (typeof options === 'object' && (typeof options.componentType !== 'undefined' || typeof options.pixelType !== 'undefined')) {
-    inputImage = castImage(image, options)
-  }
-  const inputs = [
-    { type: InterfaceTypes.Image, data: inputImage }
-  ] as PipelineInput[]
-
-  const transferables = imageTransferables(image)
-
-  const result: WriteImagePipelineResult = await workerProxy.writeImage(
-    config,
-    mimeType,
-    fileName,
-    args,
-    outputs,
-    Comlink.transfer(inputs, getTransferables(transferables))
-  )
-  return { arrayBuffer: result.outputs[0].data.data.buffer as ArrayBuffer, webWorker: worker }
-}
-
-export default writeImageArrayBuffer
diff --git a/src/io/writeImageLocalFile.ts b/src/io/writeImageLocalFile.ts
deleted file mode 100644
index 4e6887519..000000000
--- a/src/io/writeImageLocalFile.ts
+++ /dev/null
@@ -1,83 +0,0 @@
-import path from 'path'
-import mime from 'mime-types'
-
-import mimeToIO from './internal/MimeToImageIO.js'
-import getFileExtension from './getFileExtension.js'
-import extensionToIO from './extensionToImageIO.js'
-import ImageIOIndex from './internal/ImageIOIndex.js'
-
-import loadEmscriptenModule from '../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from '../pipeline/internal/runPipelineEmscripten.js'
-import PipelineEmscriptenModule from '../pipeline/PipelineEmscriptenModule.js'
-import findLocalImageIOPath from './internal/findLocalImageIOPath.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import PipelineOutput from '../pipeline/PipelineOutput.js'
-import WriteImageOptions from './WriteImageOptions.js'
-import castImage from '../core/castImage.js'
-
-import Image from '../core/interface-types/image.js'
-
-async function writeImageLocalFile (image: Image, filePath: string, options?: WriteImageOptions | boolean
-): Promise<null> {
-  if (typeof image === 'boolean') {
-    throw new Error('useCompression is now the last argument in itk-wasm')
-  }
-
-  let useCompression = false
-  if (typeof options === 'boolean') {
-    useCompression = options
-  }
-  if (typeof options === 'object' && typeof options.useCompression !== 'undefined') {
-    useCompression = options.useCompression
-  }
-
-  const imageIOsPath = findLocalImageIOPath()
-  const absoluteFilePath = path.resolve(filePath)
-  const mimeType = mime.lookup(absoluteFilePath)
-  const extension = getFileExtension(absoluteFilePath)
-
-  const args = ['0', absoluteFilePath, '--memory-io', '--quiet']
-  if (useCompression) {
-    args.push('--use-compression')
-  }
-  const desiredOutputs = [
-  ] as PipelineOutput[]
-  let inputImage = image
-  if (typeof options === 'object' && (typeof options.componentType !== 'undefined' || typeof options.pixelType !== 'undefined')) {
-    inputImage = castImage(image, options)
-  }
-  const inputs = [
-    { type: InterfaceTypes.Image, data: inputImage }
-  ] as PipelineInput[]
-
-  let io = null
-  if (mimeType !== false && mimeToIO.has(mimeType)) {
-    io = mimeToIO.get(mimeType)
-  } else if (extensionToIO.has(extension)) {
-    io = extensionToIO.get(extension)
-  } else {
-    for (let idx = 0; idx < ImageIOIndex.length; ++idx) {
-      const modulePath = path.join(imageIOsPath, ImageIOIndex[idx] + '-write-image.js')
-      const writeImageModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-      const mountedFilePath = writeImageModule.mountContainingDir(absoluteFilePath)
-      const { returnValue } = runPipelineEmscripten(writeImageModule, args, desiredOutputs, inputs)
-      writeImageModule.unmountContainingDir(mountedFilePath)
-      if (returnValue === 0) {
-        return null
-      }
-    }
-  }
-  if (io === null) {
-    throw Error('Could not find IO for: ' + absoluteFilePath)
-  }
-
-  const modulePath = path.join(imageIOsPath, io as string + '-write-image.js')
-  const writeImageModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-  const mountedFilePath = writeImageModule.mountContainingDir(absoluteFilePath)
-  runPipelineEmscripten(writeImageModule, args, desiredOutputs, inputs)
-  writeImageModule.unmountContainingDir(mountedFilePath)
-  return null
-}
-
-export default writeImageLocalFile
diff --git a/src/io/writeLocalFile.ts b/src/io/writeLocalFile.ts
deleted file mode 100644
index 38f8853a4..000000000
--- a/src/io/writeLocalFile.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import path from 'path'
-
-import getFileExtension from './getFileExtension.js'
-import extensionToMeshIO from './extensionToMeshIO.js'
-
-import writeImageLocalFile from './writeImageLocalFile.js'
-import writeMeshLocalFile from './writeMeshLocalFile.js'
-
-import Mesh from '../core/interface-types/mesh.js'
-import Image from '../core/interface-types/image.js'
-
-/**
- * Write an image or mesh to a file on the local filesystem in Node.js.
- *
- * @param: imageOrMesh itk.Image or itk.Mesh instance to write
- * @param: filePath path to the file on the local filesystem.
- * @param: useCompression compression the pixel data when possible
- *
- * @return empty Promise
- */
-async function writeLocalFile (imageOrMesh: Image | Mesh, filePath: string, useCompression: boolean = false): Promise<null> {
-  const absoluteFilePath = path.resolve(filePath)
-  const extension = getFileExtension(absoluteFilePath)
-
-  const isMesh = extensionToMeshIO.has(extension)
-  if (isMesh) {
-    try {
-      await writeMeshLocalFile(imageOrMesh as Mesh, filePath, { useCompression })
-      return null
-    } catch (err) {
-      // Was a .vtk image file? Continue to write as an image.
-      await writeImageLocalFile(imageOrMesh as Image, filePath, useCompression)
-      return null
-    }
-  } else {
-    await writeImageLocalFile(imageOrMesh as Image, filePath, useCompression)
-    return null
-  }
-}
-
-export default writeLocalFile
diff --git a/src/io/writeMeshArrayBuffer.ts b/src/io/writeMeshArrayBuffer.ts
deleted file mode 100644
index 5d48db38b..000000000
--- a/src/io/writeMeshArrayBuffer.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-import WriteMeshPipelineResult from '../core/web-workers/write-mesh-pipeline-result.js'
-
-import Mesh from '../core/interface-types/mesh.js'
-
-import config from '../itkConfig.js'
-import WriteArrayBufferResult from './WriteArrayBufferResult.js'
-import WriteMeshOptions from './WriteMeshOptions.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import PipelineOutput from '../pipeline/PipelineOutput.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import meshTransferables from '../core/internal/meshTransferables.js'
-import getTransferables from '../core/get-transferables.js'
-
-async function writeMeshArrayBuffer (webWorker: Worker | null, mesh: Mesh, fileName: string, mimeType: string, options: WriteMeshOptions): Promise<WriteArrayBufferResult> {
-  if ('useCompression' in (mesh as any) || 'binaryFileType' in (mesh as any)) {
-    throw new Error('options are now in the last argument position in itk-wasm')
-  }
-
-  let worker = webWorker
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(worker, null)
-  worker = usedWorker
-
-  const filePath = `./${fileName}`
-  const args = ['0', filePath, '--memory-io', '--quiet']
-  if (options?.useCompression === true) {
-    args.push('--use-compression')
-  }
-  if (options?.binaryFileType === true) {
-    args.push('--binary-file-type')
-  }
-  const outputs = [
-    { data: { path: filePath }, type: InterfaceTypes.BinaryFile }
-  ] as PipelineOutput[]
-  const inputs = [
-    { type: InterfaceTypes.Mesh, data: mesh }
-  ] as PipelineInput[]
-
-  const transferables = meshTransferables(mesh)
-
-  const result: WriteMeshPipelineResult = await workerProxy.writeMesh(
-    config,
-    mimeType,
-    fileName,
-    args,
-    outputs,
-    Comlink.transfer(inputs, getTransferables(transferables))
-  )
-  return { arrayBuffer: result.outputs[0].data.data.buffer as ArrayBuffer, webWorker: worker }
-}
-
-export default writeMeshArrayBuffer
diff --git a/src/io/writeMeshLocalFile.ts b/src/io/writeMeshLocalFile.ts
deleted file mode 100644
index baa11e8ec..000000000
--- a/src/io/writeMeshLocalFile.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import path from 'path'
-import mime from 'mime-types'
-
-import mimeToIO from './internal/MimeToMeshIO.js'
-import getFileExtension from './getFileExtension.js'
-import extensionToIO from './extensionToMeshIO.js'
-import MeshIOIndex from './internal/MeshIOIndex.js'
-
-import loadEmscriptenModule from '../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from '../pipeline/internal/runPipelineEmscripten.js'
-import PipelineEmscriptenModule from '../pipeline/PipelineEmscriptenModule.js'
-import findLocalMeshIOPath from './internal/findLocalMeshIOPath.js'
-import WriteMeshOptions from './WriteMeshOptions.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import PipelineInput from '../pipeline/PipelineInput.js'
-import PipelineOutput from '../pipeline/PipelineOutput.js'
-import Mesh from '../core/interface-types/mesh.js'
-
-/**
- * Write a mesh to a file on the local filesystem in Node.js.
- *
- * @param: mesh itk.Mesh instance to write
- * @param: filePath path to the file on the local filesystem.
- * @param: options.useCompression compression the pixel data when possible
- * @param: options.binaryFileType write in an binary as opposed to a ascii format, if
- * possible
- *
- * @return empty Promise
- */
-async function writeMeshLocalFile (mesh: Mesh, filePath: string, options: WriteMeshOptions): Promise<null> {
-  if ('useCompression' in (mesh as any) || 'binaryFileType' in (mesh as any)) {
-    throw new Error('options are now in the last argument position in itk-wasm')
-  }
-
-  const meshIOsPath = findLocalMeshIOPath()
-  const absoluteFilePath = path.resolve(filePath)
-  const mimeType = mime.lookup(absoluteFilePath)
-  const extension = getFileExtension(absoluteFilePath)
-
-  const args = ['0', absoluteFilePath, '--memory-io', '--quiet']
-  if (options?.useCompression === true) {
-    args.push('--use-compression')
-  }
-  if (options?.binaryFileType === true) {
-    args.push('--binary-file-type')
-  }
-  const desiredOutputs = [
-  ] as PipelineOutput[]
-  const inputs = [
-    { type: InterfaceTypes.Mesh, data: mesh }
-  ] as PipelineInput[]
-
-  let io = null
-  if (mimeType !== false && mimeToIO.has(mimeType)) {
-    io = mimeToIO.get(mimeType)
-  } else if (extensionToIO.has(extension)) {
-    io = extensionToIO.get(extension)
-  } else {
-    for (let idx = 0; idx < MeshIOIndex.length; ++idx) {
-      const modulePath = path.join(meshIOsPath, MeshIOIndex[idx] + '-write-mesh.js')
-      const writeMeshModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-      const mountedFilePath = writeMeshModule.mountContainingDir(absoluteFilePath)
-      const { returnValue } = runPipelineEmscripten(writeMeshModule, args, desiredOutputs, inputs)
-      writeMeshModule.unmountContainingDir(mountedFilePath)
-      if (returnValue === 0) {
-        return null
-      }
-    }
-  }
-  if (io === null) {
-    throw Error('Could not find IO for: ' + absoluteFilePath)
-  }
-
-  const modulePath = path.join(meshIOsPath, io as string + '-write-mesh.js')
-  const writeMeshModule = await loadEmscriptenModule(modulePath) as PipelineEmscriptenModule
-  const mountedFilePath = writeMeshModule.mountContainingDir(absoluteFilePath)
-  runPipelineEmscripten(writeMeshModule, args, desiredOutputs, inputs)
-  writeMeshModule.unmountContainingDir(mountedFilePath)
-  return null
-}
-
-export default writeMeshLocalFile
diff --git a/src/node/index.ts b/src/node/index.ts
deleted file mode 100644
index 83ea90ea7..000000000
--- a/src/node/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// itk-wasm Node API interfaces, data structures, and functions
-
-export * from '../core/index.js'
-
-export { default as ReadImageResult } from '../io/ReadImageResult.js'
-export { default as ReadMeshResult } from '../io/ReadMeshResult.js'
-
-export { default as ReadDICOMTagsResult } from '../io/deprecated/ReadDICOMTagsResult.js'
-
-export { default as WriteArrayBufferResult } from '../io/WriteArrayBufferResult.js'
-export { default as WriteMeshOptions } from '../io/WriteMeshOptions.js'
-
-export * from '../io/node/index.js'
-
-export { default as PipelineInput } from '../pipeline/PipelineInput.js'
-export { default as PipelineOutput } from '../pipeline/PipelineOutput.js'
-export { default as RunPipelineResult } from '../pipeline/RunPipelineResult.js'
-
-export * from '../pipeline/node/index.js'
diff --git a/src/pipeline/PipelineEmscriptenModule.ts b/src/pipeline/PipelineEmscriptenModule.ts
deleted file mode 100644
index a151334b9..000000000
--- a/src/pipeline/PipelineEmscriptenModule.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/// <reference types="emscripten" />
-// import { cwrap, ccall } from '@types/emscripten'
-import EmscriptenModule from "../core/ITKWasmEmscriptenModule.js";
-
-interface PipelineEmscriptenModule extends EmscriptenModule {
-  callMain: (args: string[]) => number;
-  // var c_javascript_add = Module.cwrap('c_add', // name of C function
-  // 'number', // return type
-  // ['number', 'number']); // argument types
-  cwrap: typeof cwrap;
-  ccall: typeof ccall;
-  writeArrayToMemory: typeof writeArrayToMemory;
-  writeAsciiToMemory: typeof writeAsciiToMemory;
-  AsciiToString: (ptr: number) => string;
-  stackSave: () => number;
-  stackRestore: (ptr: number) => void;
-
-  resetModuleStdout: () => void;
-  resetModuleStderr: () => void;
-  getModuleStdout: () => string;
-  getModuleStderr: () => string;
-  print: (text: string) => void;
-  printErr: (text: string) => void;
-
-  // Note: Only available if the module was built with CMAKE_BUILD_TYPE set to
-  // Debug. For example:
-  //  itk-wasm-cli build my/project -- -DCMAKE_BUILD_TYPE:STRING=Debug
-  getExceptionMessage: (num: number) => string;
-}
-
-export default PipelineEmscriptenModule;
diff --git a/src/pipeline/PipelineInput.ts b/src/pipeline/PipelineInput.ts
deleted file mode 100644
index 069ae7218..000000000
--- a/src/pipeline/PipelineInput.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import IOTypes from '../core/IOTypes.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import TextFile from '../core/interface-types/text-file.js'
-import BinaryFile from '../core/interface-types/binary-file.js'
-import TextStream from '../core/interface-types/text-stream.js'
-import BinaryStream from '../core/interface-types/binary-stream.js'
-import Image from '../core/interface-types/image.js'
-import Mesh from '../core/interface-types/mesh.js'
-import PolyData from '../core/interface-types/poly-data.js'
-import JsonCompatible from '../core/interface-types/json-compatible.js'
-
-interface PipelineInput {
-  // Backwards compatibility with IOTypes -- remove?
-  path?: string
-  type:
-  | (typeof IOTypes)[keyof typeof IOTypes]
-  | (typeof InterfaceTypes)[keyof typeof InterfaceTypes]
-  data:
-  | string
-  | Uint8Array
-  | JsonCompatible
-  | TextStream
-  | BinaryStream
-  | TextFile
-  | BinaryFile
-  | Image
-  | Mesh
-  | PolyData
-}
-
-export default PipelineInput
diff --git a/src/pipeline/PipelineOutput.ts b/src/pipeline/PipelineOutput.ts
deleted file mode 100644
index 607205475..000000000
--- a/src/pipeline/PipelineOutput.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import IOTypes from '../core/IOTypes.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import TextFile from '../core/interface-types/text-file.js'
-import BinaryFile from '../core/interface-types/binary-file.js'
-import TextStream from '../core/interface-types/text-stream.js'
-import BinaryStream from '../core/interface-types/binary-stream.js'
-import Image from '../core/interface-types/image.js'
-import Mesh from '../core/interface-types/mesh.js'
-import PolyData from '../core/interface-types/poly-data.js'
-import JsonCompatible from '../core/interface-types/json-compatible.js'
-
-interface PipelineOutput {
-  path?: string
-  type:
-  | (typeof IOTypes)[keyof typeof IOTypes]
-  | (typeof InterfaceTypes)[keyof typeof InterfaceTypes]
-  data?:
-  | string
-  | Uint8Array
-  | JsonCompatible
-  | TextStream
-  | BinaryStream
-  | TextFile
-  | BinaryFile
-  | Image
-  | Mesh
-  | PolyData
-}
-
-export default PipelineOutput
diff --git a/src/pipeline/RunPipelineOptions.ts b/src/pipeline/RunPipelineOptions.ts
deleted file mode 100644
index ed5346284..000000000
--- a/src/pipeline/RunPipelineOptions.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-interface RunPipelineOptions {
-  /** Url where WebAssembly pipelines are hosted. */
-  pipelineBaseUrl?: string | URL
-
-  /** Url where the pipeline web worker is hosted. */
-  pipelineWorkerUrl?: string | URL | null
-}
-
-export default RunPipelineOptions
diff --git a/src/pipeline/RunPipelineResult.ts b/src/pipeline/RunPipelineResult.ts
deleted file mode 100644
index 66b3237d8..000000000
--- a/src/pipeline/RunPipelineResult.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import PipelineOutput from './PipelineOutput.js'
-
-interface RunPipelineResult {
-  returnValue: number
-  stdout: string
-  stderr: string
-  outputs: PipelineOutput[]
-  webWorker?: Worker
-}
-
-export default RunPipelineResult
diff --git a/src/pipeline/browser/index.ts b/src/pipeline/browser/index.ts
deleted file mode 100644
index 4d9d8a9e4..000000000
--- a/src/pipeline/browser/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Browser pipeline functions
-
-export { default as runPipeline } from './../runPipeline.js'
-// Backwards compatibility with itk.js
-export { default as runPipelineBrowser } from './../runPipeline.js'
diff --git a/src/pipeline/internal/runPipelineEmscripten.ts b/src/pipeline/internal/runPipelineEmscripten.ts
deleted file mode 100644
index 0bb98a08a..000000000
--- a/src/pipeline/internal/runPipelineEmscripten.ts
+++ /dev/null
@@ -1,510 +0,0 @@
-import InterfaceTypes from '../../core/InterfaceTypes.js'
-import IOTypes from '../../core/IOTypes.js'
-import bufferToTypedArray from '../../core/bufferToTypedArray.js'
-import TypedArray from '../../core/TypedArray.js'
-import TextStream from '../../core/interface-types/text-stream.js'
-import BinaryStream from '../../core/interface-types/binary-stream.js'
-import TextFile from '../../core/interface-types/text-file.js'
-import BinaryFile from '../../core/interface-types/binary-file.js'
-import Image from '../../core/interface-types/image.js'
-import Mesh from '../../core/interface-types/mesh.js'
-import PolyData from '../../core/interface-types/poly-data.js'
-import FloatTypes from '../../core/interface-types/float-types.js'
-import IntTypes from '../../core/interface-types/int-types.js'
-
-import PipelineEmscriptenModule from '../PipelineEmscriptenModule.js'
-import PipelineInput from '../PipelineInput.js'
-import PipelineOutput from '../PipelineOutput.js'
-import RunPipelineResult from '../RunPipelineResult.js'
-
-const haveSharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function'
-const encoder = new TextEncoder()
-const decoder = new TextDecoder('utf-8')
-
-function readFileSharedArray (emscriptenModule: PipelineEmscriptenModule, path: string): Uint8Array {
-  const opts = { flags: 'r', encoding: 'binary' }
-  const stream = emscriptenModule.fs_open(path, opts.flags)
-  const stat = emscriptenModule.fs_stat(path)
-  const length = stat.size
-  let arrayBufferData = null
-  if (haveSharedArrayBuffer) {
-    arrayBufferData = new SharedArrayBuffer(length) // eslint-disable-line
-  } else {
-    arrayBufferData = new ArrayBuffer(length)
-  }
-  const array = new Uint8Array(arrayBufferData)
-  emscriptenModule.fs_read(stream, array, 0, length, 0)
-  emscriptenModule.fs_close(stream)
-  return array
-}
-
-function memoryUint8SharedArray (emscriptenModule: PipelineEmscriptenModule, byteOffset: number, length: number): Uint8Array {
-  let arrayBufferData = null
-  if (haveSharedArrayBuffer) {
-    arrayBufferData = new SharedArrayBuffer(length) // eslint-disable-line
-  } else {
-    arrayBufferData = new ArrayBuffer(length)
-  }
-  const array = new Uint8Array(arrayBufferData)
-  const dataArrayView = new Uint8Array(emscriptenModule.HEAPU8.buffer, byteOffset, length)
-  array.set(dataArrayView)
-  return array
-}
-
-function setPipelineModuleInputArray (emscriptenModule: PipelineEmscriptenModule, dataArray: TypedArray | null, inputIndex: number, subIndex: number): number {
-  let dataPtr = 0
-  if (dataArray !== null) {
-    dataPtr = emscriptenModule.ccall('itk_wasm_input_array_alloc', 'number', ['number', 'number', 'number', 'number'], [0, inputIndex, subIndex, dataArray.buffer.byteLength])
-    emscriptenModule.HEAPU8.set(new Uint8Array(dataArray.buffer), dataPtr)
-  }
-  return dataPtr
-}
-
-function setPipelineModuleInputJSON (emscriptenModule: PipelineEmscriptenModule, dataObject: object, inputIndex: number): void {
-  const dataJSON = JSON.stringify(dataObject)
-  const jsonPtr = emscriptenModule.ccall('itk_wasm_input_json_alloc', 'number', ['number', 'number', 'number'], [0, inputIndex, dataJSON.length])
-  emscriptenModule.writeAsciiToMemory(dataJSON, jsonPtr, false)
-}
-
-function getPipelineModuleOutputArray (emscriptenModule: PipelineEmscriptenModule, outputIndex: number, subIndex: number, componentType: typeof IntTypes[keyof typeof IntTypes] | typeof FloatTypes[keyof typeof FloatTypes]): TypedArray | Float32Array | Uint32Array | null {
-  const dataPtr = emscriptenModule.ccall('itk_wasm_output_array_address', 'number', ['number', 'number', 'number'], [0, outputIndex, subIndex])
-  const dataSize = emscriptenModule.ccall('itk_wasm_output_array_size', 'number', ['number', 'number', 'number'], [0, outputIndex, subIndex])
-  const dataUint8 = memoryUint8SharedArray(emscriptenModule, dataPtr, dataSize)
-  const data = bufferToTypedArray(componentType, dataUint8.buffer)
-  return data
-}
-
-function getPipelineModuleOutputJSON (emscriptenModule: PipelineEmscriptenModule, outputIndex: number): object {
-  const jsonPtr = emscriptenModule.ccall('itk_wasm_output_json_address', 'number', ['number', 'number'], [0, outputIndex])
-  const dataJSON = emscriptenModule.AsciiToString(jsonPtr)
-  const dataObject = JSON.parse(dataJSON)
-  return dataObject
-}
-
-function runPipelineEmscripten (pipelineModule: PipelineEmscriptenModule, args: string[], outputs: PipelineOutput[] | null, inputs: PipelineInput[] | null): RunPipelineResult {
-  if (!(inputs == null) && inputs.length > 0) {
-    inputs.forEach(function (input, index) {
-      switch (input.type) {
-        case InterfaceTypes.TextStream:
-        {
-          const dataArray = encoder.encode((input.data as TextStream).data)
-          const arrayPtr = setPipelineModuleInputArray(pipelineModule, dataArray, index, 0)
-          const dataJSON = { size: dataArray.buffer.byteLength, data: `data:application/vnd.itk.address,0:${arrayPtr}` }
-          setPipelineModuleInputJSON(pipelineModule, dataJSON, index)
-          break
-        }
-        case InterfaceTypes.JsonCompatible:
-        {
-          const dataArray = encoder.encode(JSON.stringify(input.data))
-          const arrayPtr = setPipelineModuleInputArray(pipelineModule, dataArray, index, 0)
-          const dataJSON = { size: dataArray.buffer.byteLength, data: `data:application/vnd.itk.address,0:${arrayPtr}` }
-          setPipelineModuleInputJSON(pipelineModule, dataJSON, index)
-          break
-        }
-        case InterfaceTypes.BinaryStream:
-        {
-          const dataArray = (input.data as BinaryStream).data
-          const arrayPtr = setPipelineModuleInputArray(pipelineModule, dataArray, index, 0)
-          const dataJSON = { size: dataArray.buffer.byteLength, data: `data:application/vnd.itk.address,0:${arrayPtr}` }
-          setPipelineModuleInputJSON(pipelineModule, dataJSON, index)
-          break
-        }
-        case InterfaceTypes.TextFile:
-        {
-          pipelineModule.fs_writeFile((input.data as TextFile).path, (input.data as TextFile).data)
-          break
-        }
-        case InterfaceTypes.BinaryFile:
-        {
-          pipelineModule.fs_writeFile((input.data as BinaryFile).path, (input.data as BinaryFile).data)
-          break
-        }
-        case InterfaceTypes.Image:
-        {
-          const image = input.data as Image
-          const dataPtr = setPipelineModuleInputArray(pipelineModule, image.data, index, 0)
-          const directionPtr = setPipelineModuleInputArray(pipelineModule, image.direction, index, 1)
-          const metadata = typeof image.metadata?.entries !== 'undefined' ? JSON.stringify(Array.from(image.metadata.entries())) : '[]'
-          const imageJSON = {
-            imageType: image.imageType,
-            name: image.name,
-            origin: image.origin,
-            spacing: image.spacing,
-            direction: `data:application/vnd.itk.address,0:${directionPtr}`,
-            size: image.size,
-            data: `data:application/vnd.itk.address,0:${dataPtr}`,
-            metadata
-          }
-          setPipelineModuleInputJSON(pipelineModule, imageJSON, index)
-          break
-        }
-        case InterfaceTypes.Mesh:
-        {
-          const mesh = input.data as Mesh
-          const pointsPtr = setPipelineModuleInputArray(pipelineModule, mesh.points, index, 0)
-          const cellsPtr = setPipelineModuleInputArray(pipelineModule, mesh.cells, index, 1)
-          const pointDataPtr = setPipelineModuleInputArray(pipelineModule, mesh.pointData, index, 2)
-          const cellDataPtr = setPipelineModuleInputArray(pipelineModule, mesh.cellData, index, 3)
-          const meshJSON = {
-            meshType: mesh.meshType,
-            name: mesh.name,
-
-            numberOfPoints: mesh.numberOfPoints,
-            points: `data:application/vnd.itk.address,0:${pointsPtr}`,
-
-            numberOfCells: mesh.numberOfCells,
-            cells: `data:application/vnd.itk.address,0:${cellsPtr}`,
-            cellBufferSize: mesh.cellBufferSize,
-
-            numberOfPointPixels: mesh.numberOfPointPixels,
-            pointData: `data:application/vnd.itk.address,0:${pointDataPtr}`,
-
-            numberOfCellPixels: mesh.numberOfCellPixels,
-            cellData: `data:application/vnd.itk.address,0:${cellDataPtr}`
-          }
-          setPipelineModuleInputJSON(pipelineModule, meshJSON, index)
-          break
-        }
-        case InterfaceTypes.PolyData:
-        {
-          const polyData = input.data as PolyData
-          const pointsPtr = setPipelineModuleInputArray(pipelineModule, polyData.points, index, 0)
-          const verticesPtr = setPipelineModuleInputArray(pipelineModule, polyData.vertices, index, 1)
-          const linesPtr = setPipelineModuleInputArray(pipelineModule, polyData.lines, index, 2)
-          const polygonsPtr = setPipelineModuleInputArray(pipelineModule, polyData.polygons, index, 3)
-          const triangleStripsPtr = setPipelineModuleInputArray(pipelineModule, polyData.triangleStrips, index, 4)
-          const pointDataPtr = setPipelineModuleInputArray(pipelineModule, polyData.pointData, index, 5)
-          const cellDataPtr = setPipelineModuleInputArray(pipelineModule, polyData.pointData, index, 6)
-          const polyDataJSON = {
-            polyDataType: polyData.polyDataType,
-            name: polyData.name,
-
-            numberOfPoints: polyData.numberOfPoints,
-            points: `data:application/vnd.itk.address,0:${pointsPtr}`,
-
-            verticesBufferSize: polyData.verticesBufferSize,
-            vertices: `data:application/vnd.itk.address,0:${verticesPtr}`,
-
-            linesBufferSize: polyData.linesBufferSize,
-            lines: `data:application/vnd.itk.address,0:${linesPtr}`,
-
-            polygonsBufferSize: polyData.polygonsBufferSize,
-            polygons: `data:application/vnd.itk.address,0:${polygonsPtr}`,
-
-            triangleStripsBufferSize: polyData.triangleStripsBufferSize,
-            triangleStrips: `data:application/vnd.itk.address,0:${triangleStripsPtr}`,
-
-            numberOfPointPixels: polyData.numberOfPointPixels,
-            pointData: `data:application/vnd.itk.address,0:${pointDataPtr}`,
-
-            numberOfCellPixels: polyData.numberOfCellPixels,
-            cellData: `data:application/vnd.itk.address,0:${cellDataPtr}`
-          }
-          setPipelineModuleInputJSON(pipelineModule, polyDataJSON, index)
-          break
-        }
-        case IOTypes.Text:
-        {
-          pipelineModule.fs_writeFile(input.path as string, input.data as string)
-          break
-        }
-        case IOTypes.Binary:
-        {
-          pipelineModule.fs_writeFile(input.path as string, input.data as Uint8Array)
-          break
-        }
-        case IOTypes.Image:
-        {
-          const image = input.data as Image
-          const imageJSON = {
-            imageType: image.imageType,
-            name: image.name,
-            origin: image.origin,
-            spacing: image.spacing,
-            direction: 'data:application/vnd.itk.path,data/direction.raw',
-            size: image.size,
-            data: 'data:application/vnd.itk.path,data/data.raw'
-          }
-          pipelineModule.fs_mkdirs(`${input.path as string}/data`)
-          pipelineModule.fs_writeFile(`${input.path as string}/index.json`, JSON.stringify(imageJSON))
-          if (image.data === null) {
-            throw Error('image.data is null')
-          }
-          pipelineModule.fs_writeFile(`${input.path as string}/data/data.raw`, new Uint8Array(image.data.buffer))
-          pipelineModule.fs_writeFile(`${input.path as string}/data/direction.raw`, new Uint8Array(image.direction.buffer))
-          break
-        }
-        case IOTypes.Mesh:
-        {
-          const mesh = input.data as Mesh
-          const meshJSON = {
-            meshType: mesh.meshType,
-            name: mesh.name,
-
-            numberOfPoints: mesh.numberOfPoints,
-            points: 'data:application/vnd.itk.path,data/points.raw',
-
-            numberOfPointPixels: mesh.numberOfPointPixels,
-            pointData: 'data:application/vnd.itk.path,data/pointData.raw',
-
-            numberOfCells: mesh.numberOfCells,
-            cells: 'data:application/vnd.itk.path,data/cells.raw',
-
-            numberOfCellPixels: mesh.numberOfCellPixels,
-            cellData: 'data:application/vnd.itk.path,data/cellData.raw',
-            cellBufferSize: mesh.cellBufferSize
-
-          }
-          pipelineModule.fs_mkdirs(`${input.path as string}/data`)
-          pipelineModule.fs_writeFile(`${input.path as string}/index.json`, JSON.stringify(meshJSON))
-          if (meshJSON.numberOfPoints > 0) {
-            if (mesh.points === null) {
-              throw Error('mesh.points is null')
-            }
-            pipelineModule.fs_writeFile(`${input.path as string}/data/points.raw`, new Uint8Array(mesh.points.buffer))
-          }
-          if (meshJSON.numberOfPointPixels > 0) {
-            if (mesh.pointData === null) {
-              throw Error('mesh.pointData is null')
-            }
-            pipelineModule.fs_writeFile(`${input.path as string}/data/pointData.raw`, new Uint8Array(mesh.pointData.buffer))
-          }
-          if (meshJSON.numberOfCells > 0) {
-            if (mesh.cells === null) {
-              throw Error('mesh.cells is null')
-            }
-            pipelineModule.fs_writeFile(`${input.path as string}/data/cells.raw`, new Uint8Array(mesh.cells.buffer))
-          }
-          if (meshJSON.numberOfCellPixels > 0) {
-            if (mesh.cellData === null) {
-              throw Error('mesh.cellData is null')
-            }
-            pipelineModule.fs_writeFile(`${input.path as string}/data/cellData.raw`, new Uint8Array(mesh.cellData.buffer))
-          }
-          break
-        }
-        default:
-          throw Error('Unsupported input InterfaceType')
-      }
-    })
-  }
-
-  pipelineModule.resetModuleStdout()
-  pipelineModule.resetModuleStderr()
-  const stackPtr = pipelineModule.stackSave()
-  let returnValue = 0
-  try {
-    returnValue = pipelineModule.callMain(args.slice())
-  } catch (exception) {
-    // Note: Module must be built with CMAKE_BUILD_TYPE set to Debug.
-    // e.g.: itk-wasm build my/project -- -DCMAKE_BUILD_TYPE:STRING=Debug
-    if (typeof exception === 'number') {
-      console.log('Exception while running pipeline:')
-      console.log('stdout:', pipelineModule.getModuleStdout())
-      console.error('stderr:', pipelineModule.getModuleStderr())
-      if (typeof pipelineModule.getExceptionMessage !== 'undefined') {
-        console.error('exception:', pipelineModule.getExceptionMessage(exception))
-      } else {
-        console.error('Build module in Debug mode for exception message information.')
-      }
-    }
-    throw exception
-  } finally {
-    pipelineModule.stackRestore(stackPtr)
-  }
-  const stdout = pipelineModule.getModuleStdout()
-  const stderr = pipelineModule.getModuleStderr()
-
-  const populatedOutputs: PipelineOutput[] = []
-  if (!(outputs == null) && outputs.length > 0 && returnValue === 0) {
-    outputs.forEach(function (output, index) {
-      let outputData: any = null
-      switch (output.type) {
-        case InterfaceTypes.TextStream:
-        {
-          const dataPtr = pipelineModule.ccall('itk_wasm_output_array_address', 'number', ['number', 'number', 'number'], [0, index, 0])
-          const dataSize = pipelineModule.ccall('itk_wasm_output_array_size', 'number', ['number', 'number', 'number'], [0, index, 0])
-          const dataArrayView = new Uint8Array(pipelineModule.HEAPU8.buffer, dataPtr, dataSize)
-          outputData = { data: decoder.decode(dataArrayView) }
-          break
-        }
-        case InterfaceTypes.JsonCompatible:
-        {
-          const dataPtr = pipelineModule.ccall('itk_wasm_output_array_address', 'number', ['number', 'number', 'number'], [0, index, 0])
-          const dataSize = pipelineModule.ccall('itk_wasm_output_array_size', 'number', ['number', 'number', 'number'], [0, index, 0])
-          const dataArrayView = new Uint8Array(pipelineModule.HEAPU8.buffer, dataPtr, dataSize)
-          outputData = JSON.parse(decoder.decode(dataArrayView))
-          break
-        }
-        case InterfaceTypes.BinaryStream:
-        {
-          const dataPtr = pipelineModule.ccall('itk_wasm_output_array_address', 'number', ['number', 'number', 'number'], [0, index, 0])
-          const dataSize = pipelineModule.ccall('itk_wasm_output_array_size', 'number', ['number', 'number', 'number'], [0, index, 0])
-          outputData = { data: memoryUint8SharedArray(pipelineModule, dataPtr, dataSize) }
-          break
-        }
-        case InterfaceTypes.TextFile:
-        {
-          outputData = { path: (output.data as TextFile).path, data: pipelineModule.fs_readFile((output.data as TextFile).path, { encoding: 'utf8' }) as string }
-          break
-        }
-        case InterfaceTypes.BinaryFile:
-        {
-          outputData = { path: (output.data as BinaryFile).path, data: readFileSharedArray(pipelineModule, (output.data as BinaryFile).path) }
-          break
-        }
-        case InterfaceTypes.Image:
-        {
-          const image = getPipelineModuleOutputJSON(pipelineModule, index) as Image
-          image.data = getPipelineModuleOutputArray(pipelineModule, index, 0, image.imageType.componentType)
-          image.direction = getPipelineModuleOutputArray(pipelineModule, index, 1, FloatTypes.Float64) as Float64Array
-          image.metadata = new Map(image.metadata)
-          outputData = image
-          break
-        }
-        case InterfaceTypes.Mesh:
-        {
-          const mesh = getPipelineModuleOutputJSON(pipelineModule, index) as Mesh
-          if (mesh.numberOfPoints > 0) {
-            mesh.points = getPipelineModuleOutputArray(pipelineModule, index, 0, mesh.meshType.pointComponentType)
-          } else {
-            mesh.points = bufferToTypedArray(mesh.meshType.pointComponentType, new ArrayBuffer(0))
-          }
-          if (mesh.numberOfCells > 0) {
-            mesh.cells = getPipelineModuleOutputArray(pipelineModule, index, 1, mesh.meshType.cellComponentType)
-          } else {
-            mesh.cells = bufferToTypedArray(mesh.meshType.cellComponentType, new ArrayBuffer(0))
-          }
-          if (mesh.numberOfPointPixels > 0) {
-            mesh.pointData = getPipelineModuleOutputArray(pipelineModule, index, 2, mesh.meshType.pointPixelComponentType)
-          } else {
-            mesh.pointData = bufferToTypedArray(mesh.meshType.pointPixelComponentType, new ArrayBuffer(0))
-          }
-          if (mesh.numberOfCellPixels > 0) {
-            mesh.cellData = getPipelineModuleOutputArray(pipelineModule, index, 3, mesh.meshType.cellPixelComponentType)
-          } else {
-            mesh.cellData = bufferToTypedArray(mesh.meshType.cellPixelComponentType, new ArrayBuffer(0))
-          }
-          outputData = mesh
-          break
-        }
-        case InterfaceTypes.PolyData:
-        {
-          const polyData = getPipelineModuleOutputJSON(pipelineModule, index) as PolyData
-          if (polyData.numberOfPoints > 0) {
-            polyData.points = getPipelineModuleOutputArray(pipelineModule, index, 0, FloatTypes.Float32) as Float32Array
-          } else {
-            polyData.points = new Float32Array()
-          }
-          if (polyData.verticesBufferSize > 0) {
-            polyData.vertices = getPipelineModuleOutputArray(pipelineModule, index, 1, IntTypes.UInt32) as Uint32Array
-          } else {
-            polyData.vertices = new Uint32Array()
-          }
-          if (polyData.linesBufferSize > 0) {
-            polyData.lines = getPipelineModuleOutputArray(pipelineModule, index, 2, IntTypes.UInt32) as Uint32Array
-          } else {
-            polyData.lines = new Uint32Array()
-          }
-          if (polyData.polygonsBufferSize > 0) {
-            polyData.polygons = getPipelineModuleOutputArray(pipelineModule, index, 3, IntTypes.UInt32) as Uint32Array
-          } else {
-            polyData.polygons = new Uint32Array()
-          }
-          if (polyData.triangleStripsBufferSize > 0) {
-            polyData.triangleStrips = getPipelineModuleOutputArray(pipelineModule, index, 4, IntTypes.UInt32) as Uint32Array
-          } else {
-            polyData.triangleStrips = new Uint32Array()
-          }
-          if (polyData.numberOfPointPixels > 0) {
-            polyData.pointData = getPipelineModuleOutputArray(pipelineModule, index, 5, polyData.polyDataType.pointPixelComponentType)
-          } else {
-            polyData.pointData = bufferToTypedArray(polyData.polyDataType.pointPixelComponentType, new ArrayBuffer(0))
-          }
-          if (polyData.numberOfCellPixels > 0) {
-            polyData.cellData = getPipelineModuleOutputArray(pipelineModule, index, 6, polyData.polyDataType.cellPixelComponentType)
-          } else {
-            polyData.cellData = bufferToTypedArray(polyData.polyDataType.cellPixelComponentType, new ArrayBuffer(0))
-          }
-          outputData = polyData
-          break
-        }
-        case IOTypes.Text:
-        {
-          if (typeof output.path === 'undefined') {
-            throw new Error('output.path not defined')
-          }
-          outputData = pipelineModule.fs_readFile(output.path, { encoding: 'utf8' }) as string
-          break
-        }
-        case IOTypes.Binary:
-        {
-          if (typeof output.path === 'undefined') {
-            throw new Error('output.path not defined')
-          }
-          outputData = readFileSharedArray(pipelineModule, output.path)
-          break
-        }
-        case IOTypes.Image:
-        {
-          if (typeof output.path === 'undefined') {
-            throw new Error('output.path not defined')
-          }
-          const imageJSON = pipelineModule.fs_readFile(`${output.path}/index.json`, { encoding: 'utf8' }) as string
-          const image = JSON.parse(imageJSON)
-          const dataUint8 = readFileSharedArray(pipelineModule, `${output.path}/data/data.raw`)
-          image.data = bufferToTypedArray(image.imageType.componentType, dataUint8.buffer)
-          const directionUint8 = readFileSharedArray(pipelineModule, `${output.path}/data/direction.raw`)
-          image.direction = bufferToTypedArray(FloatTypes.Float64, directionUint8.buffer)
-          outputData = image as Image
-          break
-        }
-        case IOTypes.Mesh:
-        {
-          if (typeof output.path === 'undefined') {
-            throw new Error('output.path not defined')
-          }
-          const meshJSON = pipelineModule.fs_readFile(`${output.path}/index.json`, { encoding: 'utf8' }) as string
-          const mesh = JSON.parse(meshJSON)
-          if (mesh.numberOfPoints > 0) {
-            const dataUint8Points = readFileSharedArray(pipelineModule, `${output.path}/data/points.raw`)
-            mesh.points = bufferToTypedArray(mesh.meshType.pointComponentType, dataUint8Points.buffer)
-          } else {
-            mesh.points = bufferToTypedArray(mesh.meshType.pointComponentType, new ArrayBuffer(0))
-          }
-          if (mesh.numberOfPointPixels > 0) {
-            const dataUint8PointData = readFileSharedArray(pipelineModule, `${output.path}/data/pointData.raw`)
-            mesh.pointData = bufferToTypedArray(mesh.meshType.pointPixelComponentType, dataUint8PointData.buffer)
-          } else {
-            mesh.pointData = bufferToTypedArray(mesh.meshType.pointPixelComponentType, new ArrayBuffer(0))
-          }
-          if (mesh.numberOfCells > 0) {
-            const dataUint8Cells = readFileSharedArray(pipelineModule, `${output.path}/data/cells.raw`)
-            mesh.cells = bufferToTypedArray(mesh.meshType.cellComponentType, dataUint8Cells.buffer)
-          } else {
-            mesh.cells = bufferToTypedArray(mesh.meshType.cellComponentType, new ArrayBuffer(0))
-          }
-          if (mesh.numberOfCellPixels > 0) {
-            const dataUint8CellData = readFileSharedArray(pipelineModule, `${output.path}/data/cellData.raw`)
-            mesh.cellData = bufferToTypedArray(mesh.meshType.cellPixelComponentType, dataUint8CellData.buffer)
-          } else {
-            mesh.cellData = bufferToTypedArray(mesh.meshType.cellPixelComponentType, new ArrayBuffer(0))
-          }
-          outputData = mesh as Mesh
-          break
-        }
-        default:
-          throw Error('Unsupported output InterfaceType')
-      }
-      const populatedOutput = {
-        type: output.type,
-        data: outputData
-      }
-      populatedOutputs.push(populatedOutput)
-    })
-  }
-
-  return { returnValue, stdout, stderr, outputs: populatedOutputs }
-}
-
-export default runPipelineEmscripten
diff --git a/src/pipeline/node/index.ts b/src/pipeline/node/index.ts
deleted file mode 100644
index 6c98dbb31..000000000
--- a/src/pipeline/node/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-// Node pipeline functions
-
-export { default as runPipelineNode } from './../runPipelineNode.js'
diff --git a/src/pipeline/runPipeline.ts b/src/pipeline/runPipeline.ts
deleted file mode 100644
index 6bc842ee6..000000000
--- a/src/pipeline/runPipeline.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import * as Comlink from 'comlink'
-
-import createWorkerProxy from '../core/create-worker-proxy.js'
-import loadEmscriptenModuleMainThread from '../core/internal/loadEmscriptenModuleMainThread.js'
-
-import { simd } from 'wasm-feature-detect'
-
-import config from '../itkConfig.js'
-
-import IOTypes from '../core/IOTypes.js'
-import InterfaceTypes from '../core/InterfaceTypes.js'
-import runPipelineEmscripten from './internal/runPipelineEmscripten.js'
-import getTransferables from '../core/get-transferables.js'
-import BinaryStream from '../core/interface-types/binary-stream.js'
-import BinaryFile from '../core/interface-types/binary-file.js'
-import Image from '../core/interface-types/image.js'
-import Mesh from '../core/interface-types/mesh.js'
-
-import PipelineEmscriptenModule from './PipelineEmscriptenModule.js'
-import PipelineOutput from './PipelineOutput.js'
-import PipelineInput from './PipelineInput.js'
-import RunPipelineResult from './RunPipelineResult.js'
-import RunPipelineOptions from './RunPipelineOptions.js'
-import meshTransferables from '../core/internal/meshTransferables.js'
-import TypedArray from '../core/TypedArray.js'
-import imageTransferables from '../core/internal/imageTransferables.js'
-import RunPipelineWorkerResult from '../core/web-workers/run-pipeline-worker-result.js'
-
-// To cache loaded pipeline modules
-const pipelineToModule: Map<string, PipelineEmscriptenModule> = new Map()
-
-async function loadPipelineModule (
-  pipelinePath: string | URL
-): Promise<PipelineEmscriptenModule> {
-  let moduleRelativePathOrURL: string | URL = pipelinePath as string
-  let pipeline = pipelinePath as string
-  if (typeof pipelinePath !== 'string') {
-    moduleRelativePathOrURL = new URL(pipelinePath.href)
-    pipeline = moduleRelativePathOrURL.href
-  }
-  if (pipelineToModule.has(pipeline)) {
-    return pipelineToModule.get(pipeline) as PipelineEmscriptenModule
-  } else {
-    const pipelineModule = (await loadEmscriptenModuleMainThread(
-      pipelinePath,
-      config.pipelinesUrl
-    )) as PipelineEmscriptenModule
-    pipelineToModule.set(pipeline, pipelineModule)
-    return pipelineModule
-  }
-}
-
-async function runPipeline (
-  webWorker: Worker | null | boolean,
-  pipelinePath: string | URL,
-  args: string[],
-  outputs: PipelineOutput[] | null,
-  inputs: PipelineInput[] | null,
-  options?: RunPipelineOptions
-): Promise<RunPipelineResult> {
-  if (!await simd()) {
-    const simdErrorMessage = 'WebAssembly SIMD support is required -- please update your browser.'
-    alert(simdErrorMessage)
-    throw new Error(simdErrorMessage)
-  }
-
-  if (webWorker === false) {
-    const pipelineModule = await loadPipelineModule(pipelinePath.toString())
-    const result = runPipelineEmscripten(pipelineModule, args, outputs, inputs)
-    return result
-  }
-  let worker = webWorker
-  const pipelineWorkerUrl = options?.pipelineWorkerUrl ?? null
-  const pipelineWorkerUrlString = typeof pipelineWorkerUrl !== 'string' && typeof pipelineWorkerUrl?.href !== 'undefined' ? pipelineWorkerUrl.href : pipelineWorkerUrl
-  const { workerProxy, worker: usedWorker } = await createWorkerProxy(
-    worker as Worker | null, pipelineWorkerUrlString as string | undefined | null
-  )
-  worker = usedWorker
-  const transferables: Array<ArrayBuffer | TypedArray | null> = []
-  if (!(inputs == null) && inputs.length > 0) {
-    inputs.forEach(function (input) {
-      if (input.type === InterfaceTypes.BinaryStream) {
-        // Binary data
-        const dataArray = (input.data as BinaryStream).data
-        transferables.push(dataArray)
-      } else if (input.type === InterfaceTypes.BinaryFile) {
-        // Binary data
-        const dataArray = (input.data as BinaryFile).data
-        transferables.push(dataArray)
-      } else if (input.type === InterfaceTypes.Image) {
-        // Image data
-        const image = input.data as Image
-        if (image.data === null) {
-          throw Error('image data cannot be null')
-        }
-        transferables.push(...imageTransferables(image))
-      } else if (input.type === IOTypes.Binary) {
-        // Binary data
-        transferables.push(input.data as Uint8Array)
-      } else if (input.type === IOTypes.Image) {
-        // Image data
-        const image = input.data as Image
-        if (image.data === null) {
-          throw Error('image data cannot be null')
-        }
-        transferables.push(...imageTransferables(image))
-      } else if (input.type === IOTypes.Mesh) {
-        // Mesh data
-        const mesh = input.data as Mesh
-        transferables.push(...meshTransferables(mesh))
-      }
-    })
-  }
-  const pipelineBaseUrl = options?.pipelineBaseUrl ?? 'pipelinesUrl'
-  const pipelineBaseUrlString = typeof pipelineBaseUrl !== 'string' && typeof pipelineBaseUrl?.href !== 'undefined' ? pipelineBaseUrl.href : pipelineBaseUrl
-  const transferedInputs = (inputs != null) ? Comlink.transfer(inputs, getTransferables(transferables)) : null
-  const result: RunPipelineWorkerResult = await workerProxy.runPipeline(
-    config,
-    pipelinePath.toString(),
-    pipelineBaseUrlString as string,
-    args,
-    outputs,
-    transferedInputs
-  )
-  return {
-    returnValue: result.returnValue,
-    stdout: result.stdout,
-    stderr: result.stderr,
-    outputs: result.outputs,
-    webWorker: worker
-  }
-}
-
-export default runPipeline
diff --git a/src/pipeline/runPipelineNode.ts b/src/pipeline/runPipelineNode.ts
deleted file mode 100644
index d07016fbf..000000000
--- a/src/pipeline/runPipelineNode.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import loadEmscriptenModuleNode from '../core/internal/loadEmscriptenModuleNode.js'
-import runPipelineEmscripten from './internal/runPipelineEmscripten.js'
-
-import PipelineEmscriptenModule from './PipelineEmscriptenModule.js'
-import PipelineOutput from './PipelineOutput.js'
-import PipelineInput from './PipelineInput.js'
-import RunPipelineResult from './RunPipelineResult.js'
-
-async function runPipelineNode (
-  pipelinePath: string,
-  args: string[],
-  outputs: PipelineOutput[],
-  inputs: PipelineInput[] | null,
-  mountDirs?: Set<string>
-): Promise<RunPipelineResult> {
-  const Module = (await loadEmscriptenModuleNode(
-    pipelinePath
-  )) as PipelineEmscriptenModule
-  const mountedDirs: Set<string> = new Set()
-  if (typeof mountDirs !== 'undefined') {
-    mountDirs.forEach((dir) => {
-      mountedDirs.add(Module.mountDir(dir))
-    })
-  }
-  const result = runPipelineEmscripten(Module, args, outputs, inputs)
-  if (typeof mountDirs !== 'undefined') {
-    mountedDirs.forEach((dir) => {
-      Module.unmountDir(dir)
-    })
-  }
-  return result
-}
-
-export default runPipelineNode
diff --git a/src/update-versions.cjs b/src/update-versions.cjs
deleted file mode 100644
index 829a56bda..000000000
--- a/src/update-versions.cjs
+++ /dev/null
@@ -1,27 +0,0 @@
-const fs = require('fs')
-
-let version = process.argv[2]
-if (!version) {
-  const packageString = fs.readFileSync('package.json', { encoding: 'utf-8' })
-  const packageData = JSON.parse(packageString)
-  version = packageData.version
-}
-
-function rewriteVersion(filename) {
-  if (!fs.existsSync(filename)) {
-    return
-  }
-  const lines = fs.readFileSync(filename, { encoding: 'utf-8' }).split('\n')
-  for (let i = 0; i < lines.length; i++) {
-    const line = lines[i]
-    if (lines[i].startsWith('const version = ')) {
-      lines[i] = `const version = '${version}';`
-    }
-  }
-
-  fs.writeFileSync(filename, lines.join('\n'))
-}
-
-rewriteVersion('src/core/version.ts')
-rewriteVersion('dist/core/version.js')
-rewriteVersion('dist/itkConfigDevelopment.js')
diff --git a/src/vendor-types/webworker-promise/index.d.ts b/src/vendor-types/webworker-promise/index.d.ts
deleted file mode 100644
index 80c299d50..000000000
--- a/src/vendor-types/webworker-promise/index.d.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-declare module 'webworker-promise'
-declare module 'webworker-promise/lib/register.js'
diff --git a/src/vendor-types/webworker-promise/package.json b/src/vendor-types/webworker-promise/package.json
deleted file mode 100644
index 4693c2111..000000000
--- a/src/vendor-types/webworker-promise/package.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-  name: "webworker-promise"
-}


Test patch:
diff --git a/test/browser/config/itkConfigBrowserTest.js b/test/browser/config/itkConfigBrowserTest.js
deleted file mode 100644
index 05610f6f8..000000000
--- a/test/browser/config/itkConfigBrowserTest.js
+++ /dev/null
@@ -1,8 +0,0 @@
-const itkConfig = {
-  pipelineWorkerUrl: __BASE_PATH__ + '/dist/core/web-workers/bundles/itk-wasm-pipeline.worker.js', // eslint-disable-line no-undef
-  imageIOUrl: __BASE_PATH__ + '/dist/image-io', // eslint-disable-line no-undef
-  meshIOUrl: __BASE_PATH__ + '/dist/mesh-io', // eslint-disable-line no-undef
-  pipelinesUrl: __BASE_PATH__ + '/dist/pipelines' // eslint-disable-line no-undef
-}
-
-export default itkConfig
diff --git a/test/browser/core/WebWorkerPoolTest.js b/test/browser/core/WebWorkerPoolTest.js
deleted file mode 100644
index a87ac19a0..000000000
--- a/test/browser/core/WebWorkerPoolTest.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import test from 'tape'
-import axios from 'axios'
-
-import { IntTypes, PixelTypes, readImageFile, WorkerPool, stackImages, imageSharedBufferOrCopy, runPipeline, InterfaceTypes } from 'browser/index.js'
-
-export default function () {
-  test('WorkerPool runs and reports progress', async (t) => {
-    const verifyImage = (image) => {
-      t.is(image.imageType.dimension, 2, 'dimension')
-      t.is(image.imageType.componentType, IntTypes.UInt8, 'componentType')
-      t.is(image.imageType.pixelType, PixelTypes.Scalar, 'pixelType')
-      t.is(image.imageType.components, 1, 'components')
-      t.is(image.origin[0], 0.0, 'origin[0]')
-      t.is(image.origin[1], 0.0, 'origin[1]')
-      t.is(image.spacing[0], 1.0, 'spacing[0]')
-      t.is(image.spacing[1], 1.0, 'spacing[1]')
-      t.is(image.size[0], 256, 'size[0]')
-      t.is(image.size[1], 256, 'size[1]')
-      t.is(image.data.byteLength, 65536, 'data.byteLength')
-      t.end()
-    }
-
-    const progressUpdates = []
-    let reportedTotalSplits = null
-    function progressLogger (split, totalSplits) {
-      progressUpdates.push(split)
-      reportedTotalSplits = totalSplits
-    }
-
-    const poolSize = 2
-    const maxTotalSplits = 4
-    const workerPool = new WorkerPool(poolSize, runPipeline)
-
-    const fileName = 'cthead1.png'
-    const testFilePath = 'base/build-emscripten/ExternalData/test/Input/' + fileName
-    const response = await axios.get(testFilePath, { responseType: 'blob' })
-    const jsFile = await new window.File([response.data], fileName)
-    const { image, webWorker } = await readImageFile(null, jsFile)
-    webWorker.terminate()
-
-    const taskArgsArray = []
-    for (let index = 0; index < maxTotalSplits; index++) {
-      const pipelinePath = 'median-filter-test'
-      const args = ['--memory-io', '0', '0', '--radius', '4', '-m', '' + maxTotalSplits, '-s', '' + index]
-      const desiredOutputs = [
-        { type: InterfaceTypes.Image }
-      ]
-      const data = imageSharedBufferOrCopy(image)
-      const inputs = [
-        { type: InterfaceTypes.Image, data }
-      ]
-      taskArgsArray.push([pipelinePath, args, desiredOutputs, inputs])
-    }
-
-    const results = await workerPool.runTasks(taskArgsArray, progressLogger).promise
-    workerPool.terminateWorkers()
-
-    t.is(reportedTotalSplits, maxTotalSplits, 'reported total splits')
-    const imageSplits = results.map(({ outputs }) => outputs[0].data)
-    const stackedImage = stackImages(imageSplits)
-
-    verifyImage(stackedImage)
-  })
-}
diff --git a/test/browser/core/index.js b/test/browser/core/index.js
deleted file mode 100644
index a68772d94..000000000
--- a/test/browser/core/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import WebWorkerPoolTest from './WebWorkerPoolTest.js'
-
-export default function () {
-  WebWorkerPoolTest()
-}
diff --git a/test/browser/io/index.js b/test/browser/io/index.js
deleted file mode 100644
index 855dd7200..000000000
--- a/test/browser/io/index.js
+++ /dev/null
@@ -1,9 +0,0 @@
-import readImageFileSeriesTest from './readImageFileSeriesTest.js'
-
-import meshToPolyDataTest from './meshToPolyDataTest.js'
-
-export default function () {
-  readImageFileSeriesTest()
-
-  meshToPolyDataTest()
-}
diff --git a/test/browser/io/meshToPolyDataTest.js b/test/browser/io/meshToPolyDataTest.js
deleted file mode 100644
index 519a7a875..000000000
--- a/test/browser/io/meshToPolyDataTest.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import test from 'tape'
-import axios from 'axios'
-
-import { IntTypes, FloatTypes, PixelTypes, readMeshArrayBuffer, meshToPolyData, polyDataToMesh } from 'browser/index.js'
-
-const fileName = 'cow.vtk'
-const testFilePath = 'base/build-emscripten/ExternalData/test/Input/' + fileName
-
-const verifyMesh = (t, mesh) => {
-  t.is(mesh.meshType.dimension, 3)
-  t.is(mesh.meshType.pointComponentType, FloatTypes.Float32)
-  t.is(mesh.meshType.cellComponentType, IntTypes.UInt32)
-  t.is(mesh.meshType.pointPixelType, PixelTypes.Scalar)
-  t.is(mesh.meshType.cellPixelType, PixelTypes.Scalar)
-  t.is(mesh.numberOfPoints, 2903)
-  t.is(mesh.numberOfCells, 3263)
-  t.end()
-}
-
-export default function () {
-  test('meshToPolyData converts a mesh to a polydata', async (t) => {
-    const response = await axios.get(testFilePath, { responseType: 'arraybuffer' })
-    const { mesh, webWorker } = await readMeshArrayBuffer(null, response.data, 'cow.vtk')
-    const { polyData } = await meshToPolyData(webWorker, mesh)
-    t.is(polyData.numberOfPoints, 2903)
-    t.is(polyData.polygonsBufferSize, 15593)
-    const roundTrip = await polyDataToMesh(webWorker, polyData)
-    const meshRoundTrip = roundTrip.mesh
-    webWorker.terminate()
-    t.is(meshRoundTrip.meshType.dimension, 3)
-    t.is(meshRoundTrip.meshType.pointComponentType, FloatTypes.Float32)
-    t.is(meshRoundTrip.meshType.cellComponentType, IntTypes.UInt32)
-    t.is(meshRoundTrip.meshType.pointPixelType, PixelTypes.Scalar)
-    t.is(meshRoundTrip.meshType.cellPixelType, PixelTypes.Scalar)
-    t.is(meshRoundTrip.numberOfPoints, 2903)
-    t.is(meshRoundTrip.numberOfCells, 3263)
-    verifyMesh(t, meshRoundTrip)
-  })
-}
diff --git a/test/browser/io/readTest.js b/test/browser/io/readTest.js
deleted file mode 100644
index 637e355d1..000000000
--- a/test/browser/io/readTest.js
+++ /dev/null
@@ -1,139 +0,0 @@
-import test from 'tape'
-import axios from 'axios'
-
-import { IntTypes, FloatTypes, PixelTypes, getMatrixElement, readArrayBuffer, readBlob, readFile } from 'browser/index.js'
-
-const cthead1SmallBase64DataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfhBQYVKw8AZTNIAAADdklEQVQ4y2WTa2wUVRiGp6W7O3POnLmc2VrstokJlrBIUBJigjfSICVCCAo/QKM/FFNRIESJQKAws3M7M2f20t3GthRKQQq0kkoXMIq9oFwCXkg0UpMakGLgR9EmJF4TNOvZhRBb31+TvM955/vO+T6Ou69pAgSwKCCAEPc/lYUhFEUkMgH2ESmbYocEEUmKLIQqBKmEgUlERQhAPhyJiDMXPFZZDmRGoP8Q5TwC4ciMpatfXE9zmT2NVRVIQiLi76cDUVRDT/m72zLUc/Srv+gNCi8jhCrupvMAQIWf1zJx58pRj7g7h/sduunhiIIkUAJ4AUBZ0LZev3TondmeS42TuaYms6kOapJUalYQAAKxt+j4qD3yxvMZ0z47NLi/ydhWA7GMinWyAH6G1Wwe/OdUz6dz33T35dPdIxdIYrPGK0qxTnYrobVtjm+3pNvPxGu9/dTRgw8/e89et0AKF1uFItS2u7ZP7fr4K3H19VbP94me/T6fXRifM6+a/QKC6N5+PWGYZhVeNn9pzvUoTVnt3/QEz81dUTONgwjis4UzvS2Z5JbY9JlPdxmEuFZzX9va0yu5WlXmRAlWd3Tmjg980vXBprJZbYPtza0dXw40ZleeP1ZbrWKOXXpsu7Grb3gnsY/27B46+e3ElVuF3w+sm7Pki2VAUxkAo1t0a7TL8YnVPZxy6KG9fX/+2qu/+9DARoAVBiDYaHjnfc/3nHOdicA1Em6WpnOdG/I6zwCA5PCzrn6uw6VO99gBnRBKGUyIMfz3BgmrHHta8cEdu04dN6wjPwy6FinaTNT8emKNzGrgBEmJLLf7T6Tf/60wpFP2oKToB/bNr+pVTWHjghQxZuTzW51C4aIZENdj8gMv+1f3I7iYwPEqrFu+z1/zzI3vHN/ziEd9P0haV39aXxXFRaBMRrCu9Vjj5o/S5C4QBCnjws+pJ9SoqpZmRlqyeNWlPa922El22PMCl5if38q9FGV+CeAaFuK4OZY5nLRoksnsPX19nL5do2GsREoAlCtr68lo4VoXNROWdXD8j7GUNV96AMPye5MtYgU/ujF/887tHy+PXLt9o9/asUipvDfWpc1QNFWKPfla8PHI5Ysnsua2l2dH1Un7WS6rKlamxx9f/MKKhkX1syoxmLqcUMVRDTNMlZGkilPsUrOsJ6wxRSel/wuAkzbenLRf4gAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNS0wNlQxNzoyNjozNC0wNDowMORO/MMAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDUtMDZUMTc6MjY6MzQtMDQ6MDCVE0R/AAAAAElFTkSuQmCC'
-const byteString = window.atob(cthead1SmallBase64DataURI.split(',')[1])
-const mimeString = cthead1SmallBase64DataURI.split(',')[0].split(':')[1].split(';')[0]
-const intArray = new Uint8Array(byteString.length)
-for (let ii = 0; ii < byteString.length; ++ii) {
-  intArray[ii] = byteString.charCodeAt(ii)
-}
-const cthead1SmallBlob = new window.Blob([intArray], { type: mimeString })
-const cthead1SmallFile = new window.File([cthead1SmallBlob], 'cthead1Small.png')
-
-const meshFileName = 'cow.vtk'
-const meshTestFilePath = 'base/build-emscripten/ExternalData/test/Input/' + meshFileName
-
-const verifyImage = (t, image) => {
-  t.is(image.imageType.dimension, 2, 'dimension')
-  t.is(image.imageType.componentType, IntTypes.UInt8, 'componentType')
-  t.is(image.imageType.pixelType, PixelTypes.Scalar, 'pixelType')
-  t.is(image.imageType.components, 1, 'components')
-  t.is(image.origin[0], 0.0, 'origin[0]')
-  t.is(image.origin[1], 0.0, 'origin[1]')
-  t.is(image.spacing[0], 1.0, 'spacing[0]')
-  t.is(image.spacing[1], 1.0, 'spacing[1]')
-  t.is(getMatrixElement(image.direction, 2, 0, 0), 1.0, 'direction (0, 0)')
-  t.is(getMatrixElement(image.direction, 2, 0, 1), 0.0, 'direction (0, 1)')
-  t.is(getMatrixElement(image.direction, 2, 1, 0), 0.0, 'direction (1, 0)')
-  t.is(getMatrixElement(image.direction, 2, 1, 1), 1.0, 'direction (1, 1)')
-  t.is(image.size[0], 32, 'size[0]')
-  t.is(image.size[1], 32, 'size[1]')
-  t.is(image.data.length, 1024, 'data.length')
-  t.is(image.data[512], 12, 'data[512]')
-  t.end()
-}
-
-const verifyMesh = (t, mesh) => {
-  t.is(mesh.meshType.dimension, 3)
-  t.is(mesh.meshType.pointComponentType, FloatTypes.Float32)
-  t.is(mesh.meshType.cellComponentType, IntTypes.UInt32)
-  t.is(mesh.meshType.pointPixelType, PixelTypes.Scalar)
-  t.is(mesh.meshType.cellPixelType, PixelTypes.Scalar)
-  t.is(mesh.numberOfPoints, 2903)
-  t.is(mesh.numberOfCells, 3263)
-  t.end()
-}
-
-export default function () {
-  test('readArrayBuffer reads an image ArrayBuffer', (t) => {
-    return cthead1SmallFile.arrayBuffer()
-      .then(arrayBuffer => {
-        return readArrayBuffer(null, arrayBuffer, 'cthead1Small.png')
-          .then(function ({ image, webWorker }) {
-            webWorker.terminate()
-            verifyImage(t, image)
-          })
-      })
-  })
-
-  test('readBlob reads a Blob', (t) => {
-    return readBlob(null, cthead1SmallBlob, 'cthead1Small.png')
-      .then(function ({ image, webWorker }) {
-        webWorker.terminate()
-        verifyImage(t, image)
-      })
-  })
-
-  test('readFile reads a File', (t) => {
-    return readFile(null, cthead1SmallFile)
-      .then(function ({ image, webWorker }) {
-        webWorker.terminate()
-        verifyImage(t, image)
-      })
-  })
-
-  test('readFile re-uses a WebWorker', (t) => {
-    return readFile(null, cthead1SmallFile)
-      .then(function ({ image, webWorker }) {
-        return readFile(webWorker, cthead1SmallFile)
-          .then(function ({ image, webWorker }) {
-            webWorker.terminate()
-            verifyImage(t, image)
-          })
-      })
-  })
-
-  test('readFile throws a catchable error for an invalid file', (t) => {
-    const invalidArray = new Uint8Array([21, 4, 4, 4, 4, 9, 5, 0, 82, 42])
-    const invalidBlob = new window.Blob([invalidArray])
-    const invalidFile = new window.File([invalidBlob], 'invalid.png')
-    return readFile(null, invalidFile).then(function ({ image, webWorker }) {
-      webWorker.terminate()
-      t.fail('should not have successfully read the image')
-      t.end()
-    }).catch(function (error) {
-      t.pass(String(error))
-      t.pass('thrown an error that was caught')
-      t.end()
-    })
-  })
-
-  test('readBlob reads a mesh Blob', (t) => {
-    return axios.get(meshTestFilePath, { responseType: 'blob' })
-      .then(function (response) {
-        return readBlob(null, response.data, 'cow.vtk')
-      })
-      .then(function ({ mesh, webWorker }) {
-        webWorker.terminate()
-        verifyMesh(t, mesh)
-      })
-  })
-
-  test('readFile reads a mesh File', (t) => {
-    return axios.get(meshTestFilePath, { responseType: 'blob' }).then(function (response) {
-      const jsFile = new window.File([response.data], meshFileName)
-      return jsFile
-    })
-      .then(function (jsFile) {
-        return readFile(null, jsFile)
-      })
-      .then(function ({ mesh, webWorker }) {
-        webWorker.terminate()
-        verifyMesh(t, mesh)
-      })
-  })
-
-  test('readArrayBuffer reads a mesh ArrayBuffer', (t) => {
-    return axios.get(meshTestFilePath, { responseType: 'arraybuffer' })
-      .then(function (response) {
-        return readArrayBuffer(null, response.data, 'cow.vtk')
-      })
-      .then(function ({ mesh, webWorker }) {
-        webWorker.terminate()
-        verifyMesh(t, mesh)
-      })
-  })
-}
diff --git a/test/browser/io/writeTest.js b/test/browser/io/writeTest.js
deleted file mode 100644
index 62a4407de..000000000
--- a/test/browser/io/writeTest.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import test from 'tape'
-import axios from 'axios'
-
-import { IntTypes, FloatTypes, PixelTypes, getMatrixElement, readImageArrayBuffer, readMeshArrayBuffer, writeArrayBuffer } from 'browser/index.js'
-
-const cthead1SmallBase64DataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAAAAABWESUoAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfhBQYVKw8AZTNIAAADdklEQVQ4y2WTa2wUVRiGp6W7O3POnLmc2VrstokJlrBIUBJigjfSICVCCAo/QKM/FFNRIESJQKAws3M7M2f20t3GthRKQQq0kkoXMIq9oFwCXkg0UpMakGLgR9EmJF4TNOvZhRBb31+TvM955/vO+T6Ou69pAgSwKCCAEPc/lYUhFEUkMgH2ESmbYocEEUmKLIQqBKmEgUlERQhAPhyJiDMXPFZZDmRGoP8Q5TwC4ciMpatfXE9zmT2NVRVIQiLi76cDUVRDT/m72zLUc/Srv+gNCi8jhCrupvMAQIWf1zJx58pRj7g7h/sduunhiIIkUAJ4AUBZ0LZev3TondmeS42TuaYms6kOapJUalYQAAKxt+j4qD3yxvMZ0z47NLi/ydhWA7GMinWyAH6G1Wwe/OdUz6dz33T35dPdIxdIYrPGK0qxTnYrobVtjm+3pNvPxGu9/dTRgw8/e89et0AKF1uFItS2u7ZP7fr4K3H19VbP94me/T6fXRifM6+a/QKC6N5+PWGYZhVeNn9pzvUoTVnt3/QEz81dUTONgwjis4UzvS2Z5JbY9JlPdxmEuFZzX9va0yu5WlXmRAlWd3Tmjg980vXBprJZbYPtza0dXw40ZleeP1ZbrWKOXXpsu7Grb3gnsY/27B46+e3ElVuF3w+sm7Pki2VAUxkAo1t0a7TL8YnVPZxy6KG9fX/+2qu/+9DARoAVBiDYaHjnfc/3nHOdicA1Em6WpnOdG/I6zwCA5PCzrn6uw6VO99gBnRBKGUyIMfz3BgmrHHta8cEdu04dN6wjPwy6FinaTNT8emKNzGrgBEmJLLf7T6Tf/60wpFP2oKToB/bNr+pVTWHjghQxZuTzW51C4aIZENdj8gMv+1f3I7iYwPEqrFu+z1/zzI3vHN/ziEd9P0haV39aXxXFRaBMRrCu9Vjj5o/S5C4QBCnjws+pJ9SoqpZmRlqyeNWlPa922El22PMCl5if38q9FGV+CeAaFuK4OZY5nLRoksnsPX19nL5do2GsREoAlCtr68lo4VoXNROWdXD8j7GUNV96AMPye5MtYgU/ujF/887tHy+PXLt9o9/asUipvDfWpc1QNFWKPfla8PHI5Ysnsua2l2dH1Un7WS6rKlamxx9f/MKKhkX1syoxmLqcUMVRDTNMlZGkilPsUrOsJ6wxRSel/wuAkzbenLRf4gAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNS0wNlQxNzoyNjozNC0wNDowMORO/MMAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDUtMDZUMTc6MjY6MzQtMDQ6MDCVE0R/AAAAAElFTkSuQmCC'
-const byteString = window.atob(cthead1SmallBase64DataURI.split(',')[1])
-const mimeString = cthead1SmallBase64DataURI.split(',')[0].split(':')[1].split(';')[0]
-const intArray = new Uint8Array(byteString.length)
-for (let ii = 0; ii < byteString.length; ++ii) {
-  intArray[ii] = byteString.charCodeAt(ii)
-}
-const cthead1SmallBlob = new window.Blob([intArray], { type: mimeString })
-const cthead1SmallFileWriteTest = new window.File([cthead1SmallBlob], 'cthead1Small.png')
-
-const verifyImage = (t, image) => {
-  t.is(image.imageType.dimension, 2, 'dimension')
-  t.is(image.imageType.componentType, IntTypes.UInt8, 'componentType')
-  t.is(image.imageType.pixelType, PixelTypes.Scalar, 'pixelType')
-  t.is(image.imageType.components, 1, 'components')
-  t.is(image.origin[0], 0.0, 'origin[0]')
-  t.is(image.origin[1], 0.0, 'origin[1]')
-  t.is(image.spacing[0], 1.0, 'spacing[0]')
-  t.is(image.spacing[1], 1.0, 'spacing[1]')
-  t.is(getMatrixElement(image.direction, 2, 0, 0), 1.0, 'direction (0, 0)')
-  t.is(getMatrixElement(image.direction, 2, 0, 1), 0.0, 'direction (0, 1)')
-  t.is(getMatrixElement(image.direction, 2, 1, 0), 0.0, 'direction (1, 0)')
-  t.is(getMatrixElement(image.direction, 2, 1, 1), 1.0, 'direction (1, 1)')
-  t.is(image.size[0], 32, 'size[0]')
-  t.is(image.size[1], 32, 'size[1]')
-  t.is(image.data.length, 1024, 'data.length')
-  t.is(image.data[512], 12, 'data[512]')
-  t.end()
-}
-
-const meshFileName = 'cow.vtk'
-const testMeshFilePath = 'base/build-emscripten/ExternalData/test/Input/' + meshFileName
-
-const verifyMesh = (t, mesh) => {
-  t.is(mesh.meshType.dimension, 3)
-  t.is(mesh.meshType.pointComponentType, FloatTypes.Float32)
-  t.is(mesh.meshType.cellComponentType, IntTypes.UInt32)
-  t.is(mesh.meshType.pointPixelType, PixelTypes.Scalar)
-  t.is(mesh.meshType.cellPixelType, PixelTypes.Scalar)
-  t.is(mesh.numberOfPoints, 2903)
-  t.is(mesh.numberOfCells, 3263)
-  t.end()
-}
-
-export default function () {
-  test('writeArrayBuffer writes an image to an ArrayBuffer', (t) => {
-    return cthead1SmallFileWriteTest.arrayBuffer()
-      .then((arrayBuffer) => {
-        return readImageArrayBuffer(null, arrayBuffer, 'cthead1Small.png').then(function ({ image, webWorker }) {
-          webWorker.terminate()
-          const useCompression = false
-          return writeArrayBuffer(null, useCompression, image, 'cthead1Small.png')
-        })
-      })
-      .then(function ({ arrayBuffer: writtenArrayBuffer, webWorker }) {
-        webWorker.terminate()
-        return readImageArrayBuffer(null, writtenArrayBuffer, 'cthead1Small.png').then(function ({ image }) {
-          verifyImage(t, image)
-        })
-      })
-  })
-
-  test('writeArrayBuffer writes a mesh to an ArrayBuffer', t => {
-    return axios.get(testMeshFilePath, { responseType: 'arraybuffer' })
-      .then(function (response) {
-        return readMeshArrayBuffer(null, response.data, 'cow.vtk').then(function ({ mesh, webWorker }) {
-          webWorker.terminate()
-          const useCompression = false
-          return writeArrayBuffer(null, useCompression, mesh, 'cow.vtk')
-        })
-      })
-      .then(function ({ arrayBuffer: writtenArrayBuffer, webWorker }) {
-        webWorker.terminate()
-        return readMeshArrayBuffer(null, writtenArrayBuffer, 'cow.vtk').then(function ({ mesh, webWorker }) {
-          webWorker.terminate()
-          verifyMesh(t, mesh)
-        })
-      })
-  })
-}
diff --git a/test/browser/tests.js b/test/browser/tests.js
deleted file mode 100644
index bb69bf808..000000000
--- a/test/browser/tests.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import coreTests from './core/index.js'
-import ioTests from './io/index.js'
-
-coreTests()
-ioTests()