diff --git a/justfile b/justfile
index 4801d478..fd96fb88 100644
--- a/justfile
+++ b/justfile
@@ -7,6 +7,7 @@ format:
 build-wasm target:
   cd "{{justfile_directory()}}/harper-wasm" && wasm-pack build --target {{target}}
 
+# Build `harper.js` with all size optimizations available.
 build-harperjs:
   #! /bin/bash
   set -eo pipefail
diff --git a/packages/obsidian-plugin/package.json b/packages/obsidian-plugin/package.json
index 8e43066c..0ed5826b 100644
--- a/packages/obsidian-plugin/package.json
+++ b/packages/obsidian-plugin/package.json
@@ -31,6 +31,6 @@
 	"dependencies": {
 		"crelt": "^1.0.5",
 		"lodash-es": "^4.17.21",
-		"wasm": "link:../../harper-wasm/pkg"
+		"harper.js": "link:../harper.js"
 	}
 }
diff --git a/packages/obsidian-plugin/src/HarperSettingTab.js b/packages/obsidian-plugin/src/HarperSettingTab.js
index 2b62088a..7c4ebc0b 100644
--- a/packages/obsidian-plugin/src/HarperSettingTab.js
+++ b/packages/obsidian-plugin/src/HarperSettingTab.js
@@ -58,7 +58,7 @@ function valueToString(value) {
 			return 'enable';
 		case false:
 			return 'disable';
-		case undefined:
+		case null:
 			return 'default';
 	}
 
@@ -74,7 +74,7 @@ function stringToValue(str) {
 		case 'disable':
 			return false;
 		case 'default':
-			return undefined;
+			return null;
 	}
 
 	throw 'Fell through case';
diff --git a/packages/obsidian-plugin/src/index.js b/packages/obsidian-plugin/src/index.js
index f4784edd..9a1062d6 100644
--- a/packages/obsidian-plugin/src/index.js
+++ b/packages/obsidian-plugin/src/index.js
@@ -1,8 +1,7 @@
 import logoSvg from '../logo.svg';
 import { linter } from './lint';
 import { Plugin, addIcon, Menu } from 'obsidian';
-import wasm from 'wasm/harper_wasm_bg.wasm';
-import init, { lint, get_lint_config_as_object, set_lint_config_from_object } from 'wasm';
+import { WorkerLinter } from 'harper.js';
 import { HarperSettingTab } from './HarperSettingTab';
 
 function suggestionToLabel(sug) {
@@ -13,6 +12,9 @@ function suggestionToLabel(sug) {
 	}
 }
 
+let harper = new WorkerLinter();
+harper.setup();
+
 const harperLinter = (plugin) =>
 	linter(
 		async (view) => {
@@ -22,9 +24,7 @@ const harperLinter = (plugin) =>
 
 			const text = view.state.doc.sliceString(-1);
 
-			await init(await wasm());
-
-			const lints = lint(text);
+			const lints = await harper.lint(text);
 
 			return lints.map((lint) => {
 				let span = lint.span();
@@ -81,10 +81,9 @@ export default class HarperPlugin extends Plugin {
 	/** @public
 	 * @returns {Promise<Record<string, any>>} */
 	async getSettings() {
-		await init(await wasm());
 		this.lintSettingChanged();
 
-		let lintSettings = await get_lint_config_as_object();
+		let lintSettings = await harper.getLintConfig();
 
 		return { lintSettings };
 	}
@@ -93,8 +92,6 @@ export default class HarperPlugin extends Plugin {
 	 * @param {Record<string, any>} settings
 	 * @returns {Promise<void>} */
 	async setSettings(settings) {
-		await init(await wasm());
-
 		if (settings == null) {
 			settings = {};
 		}
@@ -107,7 +104,7 @@ export default class HarperPlugin extends Plugin {
 			settings.lintSettings.spell_check = false;
 		}
 
-		set_lint_config_from_object(settings.lintSettings);
+		await harper.setLintConfig(settings.lintSettings);
 		this.lintSettingChanged();
 		this.saveData(settings);
 	}