{"_id":"neofuse","_rev":"4-e3b60899b8f6d2808d8798a769d3d153","name":"neofuse","dist-tags":{"rc":"0.0.1-rc.0","latest":"0.0.1-rc.3"},"versions":{"0.0.1-rc.0":{"name":"neofuse","version":"0.0.1-rc.0","author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"neofuse@0.0.1-rc.0","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/neofuse","bugs":{"url":"https://github.com/benallfree/neofuse/issues"},"dist":{"shasum":"9358c4eca6ad9a171415b0231d8353a1a09b1e44","tarball":"https://registry.npmjs.org/neofuse/-/neofuse-0.0.1-rc.0.tgz","fileCount":26,"integrity":"sha512-FKWxQ7ddfF0f40jDEdPq/zqw6vQlZ2Lc5plVzpxpk4OxYuaR5Nccj1hmJuaEiwYFQMIY2HrK3g+j0ayuAx1M8w==","signatures":[{"sig":"MEYCIQDJm2GzC9Em1mZW2Efqx3Eg6w87nQVSY0orbyluhQGW+AIhAJ6ZWny8lZRB6dxxMMw+wcRiD9QjdsXeTkrjEGCCfPHv","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":271382},"main":"index.js","gitHead":"3c47d3dd6fcd47c31fd6883b02f04fac69b4159f","gypfile":true,"scripts":{"test":"tape test/*.js","build":"prebuildify --napi --strip","install":"node-gyp rebuild"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"prettier":{"semi":false,"plugins":["prettier-plugin-organize-imports"],"arrowParens":"avoid","singleQuote":true,"trailingComma":"es5"},"repository":{"url":"git+https://github.com/benallfree/neofuse.git","type":"git"},"_npmVersion":"10.8.1","description":"FUSE bindings for Node","directories":{},"_nodeVersion":"20.12.0","dependencies":{"napi-macros":"^2.2.2","nanoresource":"^1.3.0","node-gyp-build":"^4.8.4"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.9.0","prettier":"^3.5.3","standard":"^17.1.2","prebuildify":"^6.0.1","concat-stream":"^2.0.0","@changesets/cli":"^2.29.4","prettier-plugin-organize-imports":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/neofuse_0.0.1-rc.0_1749398823195_0.9701822793907826","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-rc.1":{"name":"neofuse","version":"0.0.1-rc.1","author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"neofuse@0.0.1-rc.1","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/neofuse","bugs":{"url":"https://github.com/benallfree/neofuse/issues"},"dist":{"shasum":"531466c63b97959e484ce4aa9f9c3a560754d775","tarball":"https://registry.npmjs.org/neofuse/-/neofuse-0.0.1-rc.1.tgz","fileCount":28,"integrity":"sha512-6OmHGrgBWjbkXABM818gXkuubAHK+sZQNPGd12cHAuYRHYKhNDGzNne8nf5Dr87frEJdkjvxM9KcHa0KgE2pxg==","signatures":[{"sig":"MEQCIA8ePHhaIZM1g9TR6gk92kxXYgFRNteBzFenkdIq2vVMAiBc49bnfRaoLHO+PuPbvCuyHeRAlwDNi2sNSgW2OQgN5A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":280604},"types":"./index.d.ts","exports":{".":{"types":"./index.d.ts","import":"./index.js"}},"gitHead":"297f6ca0e30b02bb675b9de88529454b8309a850","gypfile":true,"scripts":{"test":"tape test/*.js","build":"prebuildify --napi --strip","install":"node-gyp rebuild"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"prettier":{"semi":false,"plugins":["prettier-plugin-organize-imports"],"arrowParens":"avoid","singleQuote":true,"trailingComma":"es5"},"repository":{"url":"git+https://github.com/benallfree/neofuse.git","type":"git"},"_npmVersion":"10.8.1","description":"FUSE bindings for Node","directories":{},"_nodeVersion":"20.12.0","dependencies":{"napi-macros":"^2.2.2","nanoresource":"^1.3.0","node-gyp-build":"^4.8.4"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.9.0","prettier":"^3.5.3","standard":"^17.1.2","prebuildify":"^6.0.1","concat-stream":"^2.0.0","@changesets/cli":"^2.29.4","prettier-plugin-organize-imports":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/neofuse_0.0.1-rc.1_1749399502527_0.9933506554546789","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-rc.2":{"name":"neofuse","version":"0.0.1-rc.2","author":{"url":"https://x.com/benallfree","name":"Ben Allfree"},"license":"MIT","_id":"neofuse@0.0.1-rc.2","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"homepage":"https://github.com/benallfree/neofuse","bugs":{"url":"https://github.com/benallfree/neofuse/issues"},"dist":{"shasum":"059e20662cf8b1539a3a8084546fb5cd00233484","tarball":"https://registry.npmjs.org/neofuse/-/neofuse-0.0.1-rc.2.tgz","fileCount":5,"integrity":"sha512-wakWbXhjTYv1gakG1qL+mD3o9/xWSP3cm3S7/LqOPJN/sCLiGaxa7vbHCfj6J2zlhAW+gGhGxDXPTRffTsVFXg==","signatures":[{"sig":"MEUCIHU5bwvrXckO4qBz05wdTUgpHIyFrJGx/jyZmio3v7rTAiEAuob7lB4yaw2PfWWVIuSP/XaePOBL2NLZIZ/lf5CnE0M=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131563},"types":"./index.d.ts","exports":{".":{"types":"./index.d.ts","import":"./index.js"}},"gitHead":"cab450f0f45d968e988218b4fc9bb6e47f50cd9e","gypfile":true,"scripts":{"test":"tape test/*.js","build":"prebuildify --napi --strip","install":"node-gyp rebuild"},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"prettier":{"semi":false,"plugins":["prettier-plugin-organize-imports"],"arrowParens":"avoid","singleQuote":true,"trailingComma":"es5"},"repository":{"url":"git+https://github.com/benallfree/neofuse.git","type":"git"},"_npmVersion":"10.8.1","description":"FUSE bindings for Node","directories":{},"_nodeVersion":"20.12.0","dependencies":{"napi-macros":"^2.2.2","nanoresource":"^1.3.0","node-gyp-build":"^4.8.4"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.9.0","prettier":"^3.5.3","standard":"^17.1.2","prebuildify":"^6.0.1","concat-stream":"^2.0.0","@changesets/cli":"^2.29.4","prettier-plugin-organize-imports":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/neofuse_0.0.1-rc.2_1749399655598_0.1666510999599622","host":"s3://npm-registry-packages-npm-production"}},"0.0.1-rc.3":{"name":"neofuse","version":"0.0.1-rc.3","description":"FUSE bindings for Node","type":"module","exports":{".":{"import":"./index.js","types":"./index.d.ts"}},"scripts":{"test":"tape test/*.js","build:darwin-x64":"prebuildify --napi --strip --platform darwin --arch x64","build:darwin-arm64":"prebuildify --napi --strip --platform darwin --arch arm64","build:linux-x64":"prebuildify --napi --strip --platform linux --arch x64","build:linux-arm64":"prebuildify --napi --strip --platform linux --arch arm64","build":"bun run clean && npm-run-all --sequential build:*","clean":"rm -rf prebuilds","install":"node-gyp rebuild"},"dependencies":{"nanoresource":"^1.3.0","node-gyp-build":"^4.8.4"},"devDependencies":{"@changesets/cli":"^2.29.4","concat-stream":"^2.0.0","napi-macros":"^2.2.2","npm-run-all":"^4.1.5","prebuildify":"^6.0.1","prettier":"^3.5.3","prettier-plugin-organize-imports":"^4.1.0","standard":"^17.1.2","tape":"^5.9.0"},"repository":{"type":"git","url":"git+https://github.com/benallfree/neofuse.git"},"author":{"name":"Ben Allfree","url":"https://x.com/benallfree"},"license":"MIT","bugs":{"url":"https://github.com/benallfree/neofuse/issues"},"homepage":"https://github.com/benallfree/neofuse","prettier":{"singleQuote":true,"trailingComma":"es5","arrowParens":"avoid","semi":false,"plugins":["prettier-plugin-organize-imports"]},"_id":"neofuse@0.0.1-rc.3","gypfile":true,"gitHead":"579429f64c29a7a9a1d74ac5459cd6c307e41fb1","types":"./index.d.ts","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-X5N4y+rk0z1XhCig16OpbgSfeYOqHtGhkjNvvAYms2jtjunVpzTNhM8iv2OamQlBtQQgrTYaQMbVHrBb5+6bfw==","shasum":"01638ca7894e4b6e282646c1d90ed2d53f323f9b","tarball":"https://registry.npmjs.org/neofuse/-/neofuse-0.0.1-rc.3.tgz","fileCount":8,"unpackedSize":348498,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHqDNnpab8WFWv91HE1OYMSEdL72LA94rhKNXBueXe0IAiEA7DbsAQyUHG4GwHotZKaNL5SdPv2R13zkB7jakKtax3I="}]},"_npmUser":{"name":"benallfree","email":"ben@benallfree.com"},"directories":{},"maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/neofuse_0.0.1-rc.3_1749438816034_0.04889419640843262"},"_hasShrinkwrap":false}},"time":{"created":"2025-06-08T16:07:03.111Z","modified":"2025-06-09T03:13:36.717Z","0.0.1-rc.0":"2025-06-08T16:07:03.377Z","0.0.1-rc.1":"2025-06-08T16:18:22.723Z","0.0.1-rc.2":"2025-06-08T16:20:55.799Z","0.0.1-rc.3":"2025-06-09T03:13:36.211Z"},"bugs":{"url":"https://github.com/benallfree/neofuse/issues"},"author":{"name":"Ben Allfree","url":"https://x.com/benallfree"},"license":"MIT","homepage":"https://github.com/benallfree/neofuse","repository":{"type":"git","url":"git+https://github.com/benallfree/neofuse.git"},"description":"FUSE bindings for Node","maintainers":[{"name":"benallfree","email":"ben@benallfree.com"}],"readme":"# neofuse\n\nMultithreaded FUSE bindings for Node.js.\n\n## Features\n\n* N-API support means we ship prebuilds and work with new Node.js releases.\n* Multithreading support means multiple calls to FUSE can run in parallel.\n* Close to feature complete in terms of the FUSE API.\n* Clean system dependency approach - uses your system's FUSE installation.\n\n## Prerequisites\n\n**neofuse requires FUSE to be installed on your system before installation.**\n\n### macOS\n```bash\nbrew install macfuse\n```\n\n### Ubuntu/Debian\n```bash\nsudo apt install libfuse-dev\n```\n\n### RHEL/CentOS/Fedora\n```bash\nsudo yum install fuse-devel\n# or on newer versions:\nsudo dnf install fuse-devel\n```\n\n### Other Linux distributions\nInstall the FUSE development package for your distribution (usually called `fuse-dev`, `libfuse-dev`, or `fuse-devel`).\n\n## Installation\n\nAfter installing FUSE on your system:\n\n```bash\nnpm install neofuse --save\n```\n\n## Example\n```js\nimport Fuse from 'neofuse'\nimport fs from 'fs'\nimport path from 'path'\n\nfunction stat(options) {\n  return {\n    mtime: new Date(),\n    atime: new Date(), \n    ctime: new Date(),\n    nlink: 1,\n    size: options.size || 0,\n    mode: options.mode === 'dir' ? 16877 : 33188,\n    uid: process.getuid ? process.getuid() : 0,\n    gid: process.getgid ? process.getgid() : 0\n  }\n}\n\nconst ops = {\n  readdir: function (path, cb) {\n    if (path === '/') return cb(null, ['test'])\n    return cb(Fuse.ENOENT)\n  },\n  getattr: function (path, cb) {\n    if (path === '/') return cb(null, stat({ mode: 'dir', size: 4096 }))\n    if (path === '/test') return cb(null, stat({ mode: 'file', size: 11 }))\n    return cb(Fuse.ENOENT)\n  },\n  open: function (path, flags, cb) {\n    return cb(0, 42)\n  },\n  release: function (path, fd, cb) {\n    return cb(0)\n  },\n  read: function (path, fd, buf, len, pos, cb) {\n    var str = 'hello world'.slice(pos, pos + len)\n    if (!str) return cb(0)\n    buf.write(str)\n    return cb(str.length)\n  }\n}\n\nconst mnt = '/tmp/fuse-test'\nconst fuse = new Fuse(mnt, ops, { debug: true })\n\nfuse.mount(function (err) {\n  if (err) throw err\n  console.log('Filesystem mounted at', mnt)\n  \n  fs.readFile(path.join(mnt, 'test'), function (err, buf) {\n    if (err) throw err\n    console.log('File contents:', buf.toString()) // Should be 'hello world'\n    \n    fuse.unmount(function (err) {\n      if (err) throw err\n      console.log('Filesystem unmounted')\n    })\n  })\n})\n```\n\n## In-Memory Filesystem Provider\n\nFor testing and development purposes, neofuse includes a built-in in-memory filesystem provider that implements a fully functional filesystem in RAM.\n\n### `createInMemoryFilesystem()`\n\nCreates a complete FUSE operations object that implements a fully functional in-memory filesystem with support for:\n\n- File operations: create, read, write, delete, truncate\n- Directory operations: create, list, delete\n- Metadata operations: permissions, timestamps, ownership\n- All other standard filesystem operations\n\n```js\nimport Fuse, { createInMemoryFilesystem } from 'neofuse'\n\nconst ops = createInMemoryFilesystem()\nconst fuse = new Fuse('./mnt', ops, { debug: true })\n\nfuse.mount(err => {\n  if (err) throw err\n  console.log('In-memory filesystem mounted!')\n  \n  // Now you can use standard filesystem operations:\n  // fs.writeFile('./mnt/test.txt', 'Hello World!')\n  // fs.mkdir('./mnt/mydir') \n  // etc.\n})\n```\n\nThis provider is perfect for:\n- **Testing**: Create isolated filesystem environments for your tests\n- **Development**: Prototype filesystem applications without persistence\n- **Demos**: Showcase FUSE functionality without complex setup\n\nThe in-memory filesystem starts empty (except for the root directory) and all data is lost when the filesystem is unmounted.\n\n## API\nIn order to create a FUSE mountpoint, you first need to create a `Fuse` object that wraps a set of implemented FUSE syscall handlers:\n\n#### `const fuse = new Fuse(mnt, handlers, opts = {})`\nCreate a new `Fuse` object.\n\n`mnt` is the string path of your desired mountpoint.\n\n`handlers` is an object mapping syscall names to implementations. The complete list of available syscalls is described below. As an example, if you wanted to implement a filesystem that only supports `getattr`, your handler object would look like:\n```js\n{\n  getattr: function (path, cb) {\n    if (path === '/') return process.nextTick(cb, null, stat({ mode: 'dir', size: 4096 }))\n    if (path === '/test') return process.nextTick(cb, null, stat({ mode: 'file', size: 11 }))\n    return process.nextTick(cb, Fuse.ENOENT)\n  }\n}\n```\n\n`opts` can include:\n```js\n{\n  displayFolder: 'Folder Name', // Add a name/icon to the mount volume on macOS\n  debug: false,  // Enable detailed tracing of operations\n  force: false,  // Attempt to unmount the mountpoint before remounting\n  mkdir: false   // Create the mountpoint before mounting\n}\n```\nAdditionally, all [FUSE-specific options](http://man7.org/linux/man-pages/man8/mount.fuse.8.html) will be passed to the underlying FUSE module (though we use camel casing instead of snake casing).\n\n#### `fuse.mount(callback)`\n\nMount the filesystem.\n\n#### `fuse.unmount(callback)` \n\nUnmount the filesystem.\n\n#### `Fuse.unmount(mountpoint, callback)`\n\nStatic method to unmount a filesystem at the given mountpoint.\n\n### FUSE API\nMost of the [FUSE API](http://fuse.sourceforge.net/doxygen/structfuse__operations.html) is supported. In general the callback for each op should be called with `cb(returnCode, [value])` where the return code is a number (`0` for OK and `< 0` for errors). See below for a list of POSIX error codes.\n\n#### `ops.init(cb)`\n\nCalled on filesystem init.\n\n#### `ops.access(path, mode, cb)`\n\nCalled before the filesystem accessed a file\n\n#### `ops.statfs(path, cb)`\n\nCalled when the filesystem is being stat'ed. Accepts a fs stat object after the return code in the callback.\n\n``` js\nops.statfs = function (path, cb) {\n  cb(0, {\n    bsize: 1000000,\n    frsize: 1000000,\n    blocks: 1000000,\n    bfree: 1000000,\n    bavail: 1000000,\n    files: 1000000,\n    ffree: 1000000,\n    favail: 1000000,\n    fsid: 1000000,\n    flag: 1000000,\n    namemax: 1000000\n  })\n}\n```\n\n#### `ops.getattr(path, cb)`\n\nCalled when a path is being stat'ed. Accepts a stat object (similar to the one returned in `fs.stat(path, cb)`) after the return code in the callback.\n\n``` js\nops.getattr = function (path, cb) {\n  cb(0, {\n    mtime: new Date(),\n    atime: new Date(),\n    ctime: new Date(),\n    size: 100,\n    mode: 16877,\n    uid: process.getuid(),\n    gid: process.getgid()\n  })\n}\n```\n\n#### `ops.fgetattr(path, fd, cb)`\n\nSame as above but is called when someone stats a file descriptor\n\n#### `ops.flush(path, fd, cb)`\n\nCalled when a file descriptor is being flushed\n\n#### `ops.fsync(path, fd, datasync, cb)`\n\nCalled when a file descriptor is being fsync'ed.\n\n#### `ops.fsyncdir(path, fd, datasync, cb)`\n\nSame as above but on a directory\n\n#### `ops.readdir(path, cb)`\n\nCalled when a directory is being listed. Accepts an array of file/directory names after the return code in the callback\n\n``` js\nops.readdir = function (path, cb) {\n  cb(0, ['file-1.txt', 'dir'])\n}\n```\n\n#### `ops.truncate(path, size, cb)`\n\nCalled when a path is being truncated to a specific size\n\n#### `ops.ftruncate(path, fd, size, cb)`\n\nSame as above but on a file descriptor\n\n#### `ops.readlink(path, cb)`\n\nCalled when a symlink is being resolved. Accepts a pathname (that the link should resolve to) after the return code in the callback\n\n``` js\nops.readlink = function (path, cb) {\n  cb(null, 'file.txt') // make link point to file.txt\n}\n```\n\n#### `ops.chown(path, uid, gid, cb)`\n\nCalled when ownership of a path is being changed\n\n#### `ops.chmod(path, mode, cb)`\n\nCalled when the mode of a path is being changed\n\n#### `ops.mknod(path, mode, dev, cb)`\n\nCalled when the a new device file is being made.\n\n#### `ops.setxattr(path, name, value, position, flags, cb)`\n\nCalled when extended attributes is being set (see the extended docs for your platform).\n\nCopy the `value` buffer somewhere to store it.\n\nThe position argument is mostly a legacy argument only used on macOS but see the getxattr docs\non Mac for more on that (you probably don't need to use that).\n\n#### `ops.getxattr(path, name, position, cb)`\n\nCalled when extended attributes is being read.\n\nReturn the extended attribute as the second argument to the callback (needs to be a buffer).\nIf no attribute is stored return `null` as the second argument.\n\nThe position argument is mostly a legacy argument only used on macOS but see the getxattr docs\non Mac for more on that (you probably don't need to use that).\n\n#### `ops.listxattr(path, cb)`\n\nCalled when extended attributes of a path are being listed.\n\nReturn a list of strings of the names of the attributes you have stored as the second argument to the callback.\n\n#### `ops.removexattr(path, name, cb)`\n\nCalled when an extended attribute is being removed.\n\n#### `ops.open(path, flags, cb)`\n\nCalled when a path is being opened. `flags` in a number containing the permissions being requested. Accepts a file descriptor after the return code in the callback.\n\n``` js\nvar toFlag = function(flags) {\n  flags = flags & 3\n  if (flags === 0) return 'r'\n  if (flags === 1) return 'w'\n  return 'r+'\n}\n\nops.open = function (path, flags, cb) {\n  var flag = toFlag(flags) // convert flags to a node style string\n  ...\n  cb(0, 42) // 42 is a file descriptor\n}\n```\n\n#### `ops.opendir(path, flags, cb)`\n\nSame as above but for directories\n\n#### `ops.read(path, fd, buffer, length, position, cb)`\n\nCalled when contents of a file is being read. You should write the result of the read to the `buffer` and return the number of bytes written as the first argument in the callback.\nIf no bytes were written (read is complete) return 0 in the callback.\n\n``` js\nvar data = new Buffer('hello world')\n\nops.read = function (path, fd, buffer, length, position, cb) {\n  if (position >= data.length) return cb(0) // done\n  var part = data.slice(position, position + length)\n  part.copy(buffer) // write the result of the read to the result buffer\n  cb(part.length) // return the number of bytes read\n}\n```\n\n#### `ops.write(path, fd, buffer, length, position, cb)`\n\nCalled when a file is being written to. You can get the data being written in `buffer` and you should return the number of bytes written in the callback as the first argument.\n\n``` js\nops.write = function (path, fd, buffer, length, position, cb) {\n  console.log('writing', buffer.slice(0, length))\n  cb(length) // we handled all the data\n}\n```\n\n#### `ops.release(path, fd, cb)`\n\nCalled when a file descriptor is being released. Happens when a read/write is done etc.\n\n#### `ops.releasedir(path, fd, cb)`\n\nSame as above but for directories\n\n#### `ops.create(path, mode, cb)`\n\nCalled when a new file is being opened.\n\n#### `ops.utimens(path, atime, mtime, cb)`\n\nCalled when the atime/mtime of a file is being changed.\n\n#### `ops.unlink(path, cb)`\n\nCalled when a file is being unlinked.\n\n#### `ops.rename(src, dest, cb)`\n\nCalled when a file is being renamed.\n\n#### `ops.link(src, dest, cb)`\n\nCalled when a new link is created.\n\n#### `ops.symlink(src, dest, cb)`\n\nCalled when a new symlink is created\n\n#### `ops.mkdir(path, mode, cb)`\n\nCalled when a new directory is being created\n\n#### `ops.rmdir(path, cb)`\n\nCalled when a directory is being removed\n\n## Error Codes\n\nFUSE operations should return appropriate POSIX error codes. neofuse provides constants for common errors:\n\n```js\nFuse.EPERM     // Operation not permitted\nFuse.ENOENT    // No such file or directory  \nFuse.EIO       // Input/output error\nFuse.EACCES    // Permission denied\nFuse.EEXIST    // File exists\nFuse.ENOTDIR   // Not a directory\nFuse.EISDIR    // Is a directory\nFuse.EINVAL    // Invalid argument\nFuse.ENOSYS    // Function not implemented\n// ... and many more\n```\n\n## Troubleshooting\n\n### \"fuse.h not found\" or similar compile errors\n\nMake sure you have installed FUSE development headers:\n\n- **macOS**: `brew install macfuse`\n- **Ubuntu/Debian**: `sudo apt install libfuse-dev` \n- **RHEL/CentOS**: `sudo yum install fuse-devel`\n\n### \"Module not found\" errors\n\nIf you get module loading errors, try rebuilding the native module:\n\n```bash\nnpm rebuild neofuse\n```\n\n### Permission errors on macOS\n\nOn macOS, you may need to allow the macFUSE kernel extension in System Settings → Privacy & Security.\n\n## License\n\nMIT for these bindings.\n\nSee the [macFUSE](https://macfuse.github.io/) license for macOS and the [libfuse](https://github.com/libfuse/libfuse) license for Linux/BSD for the system FUSE library license.\n","readmeFilename":"README.md"}