node-mlx 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,216 @@
1
+ // src/index.ts
2
+ import { platform, arch } from "os";
3
+ import { join, dirname } from "path";
4
+ import { fileURLToPath } from "url";
5
+ import { existsSync, readFileSync } from "fs";
6
+ import { createRequire } from "module";
7
+ var __filename = fileURLToPath(import.meta.url);
8
+ var __dirname = dirname(__filename);
9
+ var require2 = createRequire(import.meta.url);
10
+ var packageJsonPath = join(__dirname, "..", "package.json");
11
+ var packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
12
+ var VERSION = packageJson.version;
13
+ var binding = null;
14
+ var initialized = false;
15
+ function loadNativeAddon() {
16
+ try {
17
+ const gypBuild = require2("node-gyp-build");
18
+ const nativeDir = join(__dirname, "..", "native");
19
+ if (existsSync(join(__dirname, "..", "prebuilds"))) {
20
+ return gypBuild(join(__dirname, ".."));
21
+ }
22
+ if (existsSync(join(nativeDir, "build"))) {
23
+ return gypBuild(nativeDir);
24
+ }
25
+ } catch {
26
+ }
27
+ const possibleAddonPaths = [
28
+ // From package dist/ (npm installed)
29
+ join(__dirname, "..", "prebuilds", "darwin-arm64", "node.napi.node"),
30
+ // From native/build (local development)
31
+ join(__dirname, "..", "native", "build", "Release", "node_mlx.node"),
32
+ // From project root (monorepo development)
33
+ join(process.cwd(), "packages", "node-mlx", "native", "build", "Release", "node_mlx.node")
34
+ ];
35
+ for (const p of possibleAddonPaths) {
36
+ if (existsSync(p)) {
37
+ return require2(p);
38
+ }
39
+ }
40
+ throw new Error(
41
+ `Native addon not found. Run 'pnpm build:native' first.
42
+ Searched paths:
43
+ ${possibleAddonPaths.join("\n")}`
44
+ );
45
+ }
46
+ function findSwiftLibrary() {
47
+ const possibleDylibPaths = [
48
+ // From package swift/ (preferred - has metallib co-located)
49
+ join(__dirname, "..", "swift", "libNodeMLX.dylib"),
50
+ // From project root packages/node-mlx/swift/ (monorepo development)
51
+ join(process.cwd(), "packages", "node-mlx", "swift", "libNodeMLX.dylib"),
52
+ // Fallback to packages/swift/.build (monorepo dev)
53
+ join(__dirname, "..", "..", "swift", ".build", "release", "libNodeMLX.dylib"),
54
+ join(__dirname, "..", "..", "..", "swift", ".build", "release", "libNodeMLX.dylib"),
55
+ join(process.cwd(), "packages", "swift", ".build", "release", "libNodeMLX.dylib")
56
+ ];
57
+ for (const p of possibleDylibPaths) {
58
+ if (existsSync(p)) {
59
+ return p;
60
+ }
61
+ }
62
+ throw new Error(
63
+ `Swift library not found. Run 'pnpm build:swift' first.
64
+ Searched paths:
65
+ ${possibleDylibPaths.join("\n")}`
66
+ );
67
+ }
68
+ function loadBinding() {
69
+ if (binding && initialized) {
70
+ return binding;
71
+ }
72
+ if (platform() !== "darwin" || arch() !== "arm64") {
73
+ throw new Error("node-mlx is only supported on macOS Apple Silicon (arm64)");
74
+ }
75
+ binding = loadNativeAddon();
76
+ const dylibPath = findSwiftLibrary();
77
+ const success = binding.initialize(dylibPath);
78
+ if (!success) {
79
+ throw new Error("Failed to initialize node-mlx native library");
80
+ }
81
+ initialized = true;
82
+ return binding;
83
+ }
84
+ var RECOMMENDED_MODELS = {
85
+ // Qwen 2.5 (Alibaba) - Working with proper RoPE support
86
+ // Using non-quantized models - quantized models have loading issues
87
+ qwen: "Qwen/Qwen2.5-1.5B-Instruct",
88
+ "qwen-2.5": "Qwen/Qwen2.5-1.5B-Instruct",
89
+ "qwen-2.5-0.5b": "Qwen/Qwen2.5-0.5B-Instruct",
90
+ "qwen-2.5-1.5b": "Qwen/Qwen2.5-1.5B-Instruct",
91
+ "qwen-2.5-3b": "Qwen/Qwen2.5-3B-Instruct",
92
+ // Phi (Microsoft) - Working with fused QKV and RoPE
93
+ phi: "microsoft/phi-4",
94
+ // Default to latest
95
+ phi4: "microsoft/phi-4",
96
+ "phi-4": "microsoft/phi-4",
97
+ phi3: "microsoft/Phi-3-mini-4k-instruct",
98
+ "phi-3": "microsoft/Phi-3-mini-4k-instruct",
99
+ "phi-3-mini": "microsoft/Phi-3-mini-4k-instruct",
100
+ // Llama 3.2 (Meta) - Requires HuggingFace authentication
101
+ // Note: meta-llama models require accepting license at huggingface.co
102
+ llama: "meta-llama/Llama-3.2-1B-Instruct",
103
+ "llama-3.2": "meta-llama/Llama-3.2-1B-Instruct",
104
+ "llama-3.2-1b": "meta-llama/Llama-3.2-1B-Instruct",
105
+ "llama-3.2-3b": "meta-llama/Llama-3.2-3B-Instruct",
106
+ // Gemma 3 (Google) - Standard transformer architecture with sliding window
107
+ gemma: "mlx-community/gemma-3-1b-it-4bit",
108
+ "gemma-3": "mlx-community/gemma-3-1b-it-4bit",
109
+ "gemma-3-1b": "mlx-community/gemma-3-1b-it-4bit",
110
+ "gemma-3-1b-bf16": "mlx-community/gemma-3-1b-it-bf16",
111
+ "gemma-3-4b": "mlx-community/gemma-3-4b-it-4bit",
112
+ "gemma-3-4b-bf16": "mlx-community/gemma-3-4b-it-bf16",
113
+ "gemma-3-12b": "mlx-community/gemma-3-12b-it-4bit",
114
+ "gemma-3-27b": "mlx-community/gemma-3-27b-it-4bit"
115
+ };
116
+ function isPlatformSupported() {
117
+ return platform() === "darwin" && arch() === "arm64";
118
+ }
119
+ function isSupported() {
120
+ if (!isPlatformSupported()) {
121
+ return false;
122
+ }
123
+ try {
124
+ const b = loadBinding();
125
+ return b.isAvailable();
126
+ } catch {
127
+ return false;
128
+ }
129
+ }
130
+ function getVersion() {
131
+ const b = loadBinding();
132
+ return b.getVersion();
133
+ }
134
+ function loadModel(modelId) {
135
+ const b = loadBinding();
136
+ const handle = b.loadModel(modelId);
137
+ return {
138
+ handle,
139
+ generate(prompt, options) {
140
+ const jsonStr = b.generate(handle, prompt, {
141
+ maxTokens: options?.maxTokens ?? 256,
142
+ temperature: options?.temperature ?? 0.7,
143
+ topP: options?.topP ?? 0.9,
144
+ repetitionPenalty: options?.repetitionPenalty ?? 0,
145
+ repetitionContextSize: options?.repetitionContextSize ?? 20
146
+ });
147
+ const result = JSON.parse(jsonStr);
148
+ if (!result.success) {
149
+ throw new Error(result.error ?? "Generation failed");
150
+ }
151
+ return {
152
+ text: result.text ?? "",
153
+ tokenCount: result.tokenCount ?? 0,
154
+ tokensPerSecond: result.tokensPerSecond ?? 0
155
+ };
156
+ },
157
+ generateStreaming(prompt, options) {
158
+ const jsonStr = b.generateStreaming(handle, prompt, {
159
+ maxTokens: options?.maxTokens ?? 256,
160
+ temperature: options?.temperature ?? 0.7,
161
+ topP: options?.topP ?? 0.9,
162
+ repetitionPenalty: options?.repetitionPenalty ?? 0,
163
+ repetitionContextSize: options?.repetitionContextSize ?? 20
164
+ });
165
+ const result = JSON.parse(jsonStr);
166
+ if (!result.success) {
167
+ throw new Error(result.error ?? "Generation failed");
168
+ }
169
+ return {
170
+ tokenCount: result.tokenCount ?? 0,
171
+ tokensPerSecond: result.tokensPerSecond ?? 0
172
+ };
173
+ },
174
+ generateWithImage(prompt, imagePath, options) {
175
+ const jsonStr = b.generateWithImage(handle, prompt, imagePath, {
176
+ maxTokens: options?.maxTokens ?? 256,
177
+ temperature: options?.temperature ?? 0.7,
178
+ topP: options?.topP ?? 0.9,
179
+ repetitionPenalty: options?.repetitionPenalty ?? 0,
180
+ repetitionContextSize: options?.repetitionContextSize ?? 20
181
+ });
182
+ const result = JSON.parse(jsonStr);
183
+ if (!result.success) {
184
+ throw new Error(result.error ?? "Generation failed");
185
+ }
186
+ return {
187
+ tokenCount: result.tokenCount ?? 0,
188
+ tokensPerSecond: result.tokensPerSecond ?? 0
189
+ };
190
+ },
191
+ isVLM() {
192
+ return b.isVLM(handle);
193
+ },
194
+ unload() {
195
+ b.unloadModel(handle);
196
+ }
197
+ };
198
+ }
199
+ function generate(modelId, prompt, options) {
200
+ const model = loadModel(modelId);
201
+ try {
202
+ return model.generate(prompt, options);
203
+ } finally {
204
+ model.unload();
205
+ }
206
+ }
207
+ export {
208
+ RECOMMENDED_MODELS,
209
+ VERSION,
210
+ generate,
211
+ getVersion,
212
+ isPlatformSupported,
213
+ isSupported,
214
+ loadModel
215
+ };
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { platform, arch } from \"node:os\"\nimport { join, dirname } from \"node:path\"\nimport { fileURLToPath } from \"node:url\"\nimport { existsSync, readFileSync } from \"node:fs\"\nimport { createRequire } from \"node:module\"\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\nconst require = createRequire(import.meta.url)\n\n// Read version from package.json\nconst packageJsonPath = join(__dirname, \"..\", \"package.json\")\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")) as { version: string }\n\n/** Package version */\nexport const VERSION = packageJson.version\n\n// Native binding interface\ninterface NativeBinding {\n initialize(dylibPath: string): boolean\n isInitialized(): boolean\n loadModel(modelId: string): number\n unloadModel(handle: number): void\n generate(\n handle: number,\n prompt: string,\n options?: {\n maxTokens?: number\n temperature?: number\n topP?: number\n repetitionPenalty?: number\n repetitionContextSize?: number\n }\n ): string // Returns JSON string\n generateStreaming(\n handle: number,\n prompt: string,\n options?: {\n maxTokens?: number\n temperature?: number\n topP?: number\n repetitionPenalty?: number\n repetitionContextSize?: number\n }\n ): string // Streams to stdout, returns JSON stats\n generateWithImage(\n handle: number,\n prompt: string,\n imagePath: string,\n options?: {\n maxTokens?: number\n temperature?: number\n topP?: number\n repetitionPenalty?: number\n repetitionContextSize?: number\n }\n ): string // VLM: Streams to stdout, returns JSON stats\n isVLM(handle: number): boolean\n isAvailable(): boolean\n getVersion(): string\n}\n\n// JSON response from Swift\ninterface JSONGenerationResult {\n success: boolean\n text?: string\n tokenCount?: number\n tokensPerSecond?: number\n error?: string\n}\n\n// Load the native addon\nlet binding: NativeBinding | null = null\nlet initialized = false\n\n/**\n * Load native addon using node-gyp-build (prebuilds) or fallback to built addon\n */\nfunction loadNativeAddon(): NativeBinding {\n // Try node-gyp-build first (prebuilds)\n try {\n const gypBuild = require(\"node-gyp-build\") as (dir: string) => NativeBinding\n const nativeDir = join(__dirname, \"..\", \"native\")\n\n if (existsSync(join(__dirname, \"..\", \"prebuilds\"))) {\n return gypBuild(join(__dirname, \"..\"))\n }\n\n // Fallback to native/build if no prebuilds\n if (existsSync(join(nativeDir, \"build\"))) {\n return gypBuild(nativeDir)\n }\n } catch {\n // node-gyp-build failed, try manual loading\n }\n\n // Manual fallback: try different paths for the native addon\n const possibleAddonPaths = [\n // From package dist/ (npm installed)\n join(__dirname, \"..\", \"prebuilds\", \"darwin-arm64\", \"node.napi.node\"),\n // From native/build (local development)\n join(__dirname, \"..\", \"native\", \"build\", \"Release\", \"node_mlx.node\"),\n // From project root (monorepo development)\n join(process.cwd(), \"packages\", \"node-mlx\", \"native\", \"build\", \"Release\", \"node_mlx.node\")\n ]\n\n for (const p of possibleAddonPaths) {\n if (existsSync(p)) {\n return require(p) as NativeBinding\n }\n }\n\n throw new Error(\n \"Native addon not found. Run 'pnpm build:native' first.\\n\" +\n `Searched paths:\\n${possibleAddonPaths.join(\"\\n\")}`\n )\n}\n\n/**\n * Find Swift library path\n * Note: The library is expected to be in a directory with mlx.metallib for MLX to find it\n */\nfunction findSwiftLibrary(): string {\n const possibleDylibPaths = [\n // From package swift/ (preferred - has metallib co-located)\n join(__dirname, \"..\", \"swift\", \"libNodeMLX.dylib\"),\n // From project root packages/node-mlx/swift/ (monorepo development)\n join(process.cwd(), \"packages\", \"node-mlx\", \"swift\", \"libNodeMLX.dylib\"),\n // Fallback to packages/swift/.build (monorepo dev)\n join(__dirname, \"..\", \"..\", \"swift\", \".build\", \"release\", \"libNodeMLX.dylib\"),\n join(__dirname, \"..\", \"..\", \"..\", \"swift\", \".build\", \"release\", \"libNodeMLX.dylib\"),\n join(process.cwd(), \"packages\", \"swift\", \".build\", \"release\", \"libNodeMLX.dylib\")\n ]\n\n for (const p of possibleDylibPaths) {\n if (existsSync(p)) {\n return p\n }\n }\n\n throw new Error(\n \"Swift library not found. Run 'pnpm build:swift' first.\\n\" +\n `Searched paths:\\n${possibleDylibPaths.join(\"\\n\")}`\n )\n}\n\nfunction loadBinding(): NativeBinding {\n if (binding && initialized) {\n return binding\n }\n\n if (platform() !== \"darwin\" || arch() !== \"arm64\") {\n throw new Error(\"node-mlx is only supported on macOS Apple Silicon (arm64)\")\n }\n\n binding = loadNativeAddon()\n const dylibPath = findSwiftLibrary()\n const success = binding.initialize(dylibPath)\n\n if (!success) {\n throw new Error(\"Failed to initialize node-mlx native library\")\n }\n\n initialized = true\n\n return binding\n}\n\n// MARK: - Public Types\n\nexport interface GenerationOptions {\n maxTokens?: number\n temperature?: number\n topP?: number\n /** Penalty for repeating tokens (1.0 = no penalty, 1.1-1.2 recommended) */\n repetitionPenalty?: number\n /** Number of recent tokens to consider for penalty (default: 20) */\n repetitionContextSize?: number\n}\n\nexport interface GenerationResult {\n text: string\n tokenCount: number\n tokensPerSecond: number\n}\n\nexport interface StreamingResult {\n tokenCount: number\n tokensPerSecond: number\n}\n\nexport interface Model {\n /** Generate text from a prompt */\n generate(prompt: string, options?: GenerationOptions): GenerationResult\n\n /** Generate text with streaming - tokens are written directly to stdout */\n generateStreaming(prompt: string, options?: GenerationOptions): StreamingResult\n\n /** Generate text from a prompt with an image (VLM only) */\n generateWithImage(prompt: string, imagePath: string, options?: GenerationOptions): StreamingResult\n\n /** Check if this model supports images (is a Vision-Language Model) */\n isVLM(): boolean\n\n /** Unload the model from memory */\n unload(): void\n\n /** Model handle (internal use) */\n readonly handle: number\n}\n\n// MARK: - Recommended Models\n\nexport const RECOMMENDED_MODELS = {\n // Qwen 2.5 (Alibaba) - Working with proper RoPE support\n // Using non-quantized models - quantized models have loading issues\n qwen: \"Qwen/Qwen2.5-1.5B-Instruct\",\n \"qwen-2.5\": \"Qwen/Qwen2.5-1.5B-Instruct\",\n \"qwen-2.5-0.5b\": \"Qwen/Qwen2.5-0.5B-Instruct\",\n \"qwen-2.5-1.5b\": \"Qwen/Qwen2.5-1.5B-Instruct\",\n \"qwen-2.5-3b\": \"Qwen/Qwen2.5-3B-Instruct\",\n\n // Phi (Microsoft) - Working with fused QKV and RoPE\n phi: \"microsoft/phi-4\", // Default to latest\n phi4: \"microsoft/phi-4\",\n \"phi-4\": \"microsoft/phi-4\",\n phi3: \"microsoft/Phi-3-mini-4k-instruct\",\n \"phi-3\": \"microsoft/Phi-3-mini-4k-instruct\",\n \"phi-3-mini\": \"microsoft/Phi-3-mini-4k-instruct\",\n\n // Llama 3.2 (Meta) - Requires HuggingFace authentication\n // Note: meta-llama models require accepting license at huggingface.co\n llama: \"meta-llama/Llama-3.2-1B-Instruct\",\n \"llama-3.2\": \"meta-llama/Llama-3.2-1B-Instruct\",\n \"llama-3.2-1b\": \"meta-llama/Llama-3.2-1B-Instruct\",\n \"llama-3.2-3b\": \"meta-llama/Llama-3.2-3B-Instruct\",\n\n // Gemma 3 (Google) - Standard transformer architecture with sliding window\n gemma: \"mlx-community/gemma-3-1b-it-4bit\",\n \"gemma-3\": \"mlx-community/gemma-3-1b-it-4bit\",\n \"gemma-3-1b\": \"mlx-community/gemma-3-1b-it-4bit\",\n \"gemma-3-1b-bf16\": \"mlx-community/gemma-3-1b-it-bf16\",\n \"gemma-3-4b\": \"mlx-community/gemma-3-4b-it-4bit\",\n \"gemma-3-4b-bf16\": \"mlx-community/gemma-3-4b-it-bf16\",\n \"gemma-3-12b\": \"mlx-community/gemma-3-12b-it-4bit\",\n \"gemma-3-27b\": \"mlx-community/gemma-3-27b-it-4bit\"\n} as const\n\nexport type RecommendedModelKey = keyof typeof RECOMMENDED_MODELS\n\n// MARK: - Public API\n\n/**\n * Check if the platform is Apple Silicon Mac\n */\nexport function isPlatformSupported(): boolean {\n return platform() === \"darwin\" && arch() === \"arm64\"\n}\n\n/**\n * Check if MLX is available on this system\n * (requires macOS 14+ on Apple Silicon with built binaries)\n */\nexport function isSupported(): boolean {\n if (!isPlatformSupported()) {\n return false\n }\n\n try {\n const b = loadBinding()\n\n return b.isAvailable()\n } catch {\n return false\n }\n}\n\n/**\n * Get the library version\n */\nexport function getVersion(): string {\n const b = loadBinding()\n\n return b.getVersion()\n}\n\n/**\n * Load a model from HuggingFace or local path\n *\n * @param modelId - HuggingFace model ID (e.g., \"mlx-community/gemma-3n-E2B-it-4bit\") or local path\n * @returns Model instance\n *\n * @example\n * ```typescript\n * import { loadModel, RECOMMENDED_MODELS } from \"node-mlx\"\n *\n * const model = loadModel(RECOMMENDED_MODELS[\"gemma-3n-2b\"])\n * const result = model.generate(\"Hello, world!\")\n * console.log(result.text)\n * model.unload()\n * ```\n */\nexport function loadModel(modelId: string): Model {\n const b = loadBinding()\n const handle = b.loadModel(modelId)\n\n return {\n handle,\n\n generate(prompt: string, options?: GenerationOptions): GenerationResult {\n const jsonStr = b.generate(handle, prompt, {\n maxTokens: options?.maxTokens ?? 256,\n temperature: options?.temperature ?? 0.7,\n topP: options?.topP ?? 0.9,\n repetitionPenalty: options?.repetitionPenalty ?? 0,\n repetitionContextSize: options?.repetitionContextSize ?? 20\n })\n\n const result = JSON.parse(jsonStr) as JSONGenerationResult\n\n if (!result.success) {\n throw new Error(result.error ?? \"Generation failed\")\n }\n\n return {\n text: result.text ?? \"\",\n tokenCount: result.tokenCount ?? 0,\n tokensPerSecond: result.tokensPerSecond ?? 0\n }\n },\n\n generateStreaming(prompt: string, options?: GenerationOptions): StreamingResult {\n // Tokens are written directly to stdout by Swift\n const jsonStr = b.generateStreaming(handle, prompt, {\n maxTokens: options?.maxTokens ?? 256,\n temperature: options?.temperature ?? 0.7,\n topP: options?.topP ?? 0.9,\n repetitionPenalty: options?.repetitionPenalty ?? 0,\n repetitionContextSize: options?.repetitionContextSize ?? 20\n })\n\n const result = JSON.parse(jsonStr) as JSONGenerationResult\n\n if (!result.success) {\n throw new Error(result.error ?? \"Generation failed\")\n }\n\n return {\n tokenCount: result.tokenCount ?? 0,\n tokensPerSecond: result.tokensPerSecond ?? 0\n }\n },\n\n generateWithImage(\n prompt: string,\n imagePath: string,\n options?: GenerationOptions\n ): StreamingResult {\n // VLM generation with image - tokens are written directly to stdout by Swift\n const jsonStr = b.generateWithImage(handle, prompt, imagePath, {\n maxTokens: options?.maxTokens ?? 256,\n temperature: options?.temperature ?? 0.7,\n topP: options?.topP ?? 0.9,\n repetitionPenalty: options?.repetitionPenalty ?? 0,\n repetitionContextSize: options?.repetitionContextSize ?? 20\n })\n\n const result = JSON.parse(jsonStr) as JSONGenerationResult\n\n if (!result.success) {\n throw new Error(result.error ?? \"Generation failed\")\n }\n\n return {\n tokenCount: result.tokenCount ?? 0,\n tokensPerSecond: result.tokensPerSecond ?? 0\n }\n },\n\n isVLM(): boolean {\n return b.isVLM(handle)\n },\n\n unload(): void {\n b.unloadModel(handle)\n }\n }\n}\n\n/**\n * Generate text using a model (one-shot, loads and unloads model)\n *\n * @param modelId - HuggingFace model ID or local path\n * @param prompt - Input text\n * @param options - Generation options\n * @returns Generation result\n *\n * @example\n * ```typescript\n * import { generate } from \"node-mlx\"\n *\n * const result = generate(\n * \"mlx-community/gemma-3n-E2B-it-4bit\",\n * \"Explain quantum computing\",\n * { maxTokens: 100 }\n * )\n * console.log(result.text)\n * ```\n */\nexport function generate(\n modelId: string,\n prompt: string,\n options?: GenerationOptions\n): GenerationResult {\n const model = loadModel(modelId)\n\n try {\n return model.generate(prompt, options)\n } finally {\n model.unload()\n }\n}\n"],"mappings":"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","names":["require"]}
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "node-mlx",
3
+ "version": "1.0.0",
4
+ "description": "LLM inference for Node.js powered by Apple MLX on Apple Silicon",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "node-mlx": "./dist/cli.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "prebuilds",
22
+ "swift"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "build:swift": "cd ../swift && ./generate-version.sh && swift build -c release && ./copy-artifacts.sh",
27
+ "build:native": "cd native && node-gyp rebuild",
28
+ "prebuildify": "cd native && prebuildify --napi --strip -t 20.0.0 -t 22.0.0 -t 24.0.0 && rm -rf ../prebuilds && mv prebuilds ../",
29
+ "clean": "rm -rf dist native/build prebuilds swift",
30
+ "dev": "DYLD_FRAMEWORK_PATH=../swift/.build/release tsx src/cli.ts",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest",
33
+ "test:coverage": "vitest run --coverage",
34
+ "typecheck": "tsc --noEmit",
35
+ "lint": "eslint src/",
36
+ "prepublishOnly": "npm run build",
37
+ "release": "release-it"
38
+ },
39
+ "keywords": [
40
+ "llm",
41
+ "mlx",
42
+ "apple-silicon",
43
+ "inference",
44
+ "ai",
45
+ "machine-learning",
46
+ "gemma",
47
+ "llama",
48
+ "qwen",
49
+ "phi",
50
+ "macos",
51
+ "native",
52
+ "binding"
53
+ ],
54
+ "author": "Sebastian Werner",
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/sebastian-software/node-mlx.git",
58
+ "directory": "packages/node-mlx"
59
+ },
60
+ "bugs": {
61
+ "url": "https://github.com/sebastian-software/node-mlx/issues"
62
+ },
63
+ "homepage": "https://github.com/sebastian-software/node-mlx#readme",
64
+ "dependencies": {
65
+ "node-addon-api": "^8.5.0",
66
+ "node-gyp-build": "^4.8.4"
67
+ },
68
+ "devDependencies": {
69
+ "@release-it/conventional-changelog": "^10.0.4",
70
+ "@types/node": "^22.0.0",
71
+ "@vitest/coverage-v8": "^4.0.16",
72
+ "prebuildify": "^6.0.1",
73
+ "release-it": "^19.2.3",
74
+ "tsup": "^8.5.1",
75
+ "tsx": "^4.21.0",
76
+ "typescript": "^5.9.3",
77
+ "vitest": "^4.0.16"
78
+ },
79
+ "os": [
80
+ "darwin"
81
+ ],
82
+ "cpu": [
83
+ "arm64"
84
+ ],
85
+ "engines": {
86
+ "node": ">=20.0.0"
87
+ },
88
+ "license": "MIT"
89
+ }
Binary file
Binary file
@@ -0,0 +1,40 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>BuildMachineOSBuild</key>
6
+ <string>25C56</string>
7
+ <key>CFBundleDevelopmentRegion</key>
8
+ <string>en</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>mlx-swift.Cmlx.resources</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>mlx-swift_Cmlx</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>BNDL</string>
17
+ <key>CFBundleSupportedPlatforms</key>
18
+ <array>
19
+ <string>MacOSX</string>
20
+ </array>
21
+ <key>DTCompiler</key>
22
+ <string>com.apple.compilers.llvm.clang.1_0</string>
23
+ <key>DTPlatformBuild</key>
24
+ <string>25C57</string>
25
+ <key>DTPlatformName</key>
26
+ <string>macosx</string>
27
+ <key>DTPlatformVersion</key>
28
+ <string>26.2</string>
29
+ <key>DTSDKBuild</key>
30
+ <string>25C57</string>
31
+ <key>DTSDKName</key>
32
+ <string>macosx26.2</string>
33
+ <key>DTXcode</key>
34
+ <string>2620</string>
35
+ <key>DTXcodeBuild</key>
36
+ <string>17C52</string>
37
+ <key>LSMinimumSystemVersion</key>
38
+ <string>13.3</string>
39
+ </dict>
40
+ </plist>
Binary file