{"id":24911,"library":"apipublisher","title":"ApiPublisher","description":"ApiPublisher is a Node.js framework for exposing asynchronous JavaScript APIs (returning Promises) over HTTP, enabling identical async function calls on client and server. Current version 2.1.5 requires Node >=10.0.0. It ships TypeScript types. Key differentiators: works seamlessly with Connect/Express, supports ES7 async/await via Nodent, offers browser RemoteApi with caching (including localStorage), and has been in production since 2013. Unlike generic RPC libraries, it preserves Promise semantics and supports nested APIs automatically.","status":"active","version":"2.1.5","language":"javascript","source_language":"en","source_url":"https://github.com/MatAtBread/ApiPublisher","tags":["javascript","Javascript","asynchronous","remote","ES7","async","await","Promise","typescript"],"install":[{"cmd":"npm install apipublisher","lang":"bash","label":"npm"},{"cmd":"yarn add apipublisher","lang":"bash","label":"yarn"},{"cmd":"pnpm add apipublisher","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ESM-only since v2.0.0 (package.json type: module). Default export not available; use named import.","wrong":"const ApiPublisher = require('apipublisher')","symbol":"ApiPublisher","correct":"import { ApiPublisher } from 'apipublisher'"},{"note":"TypeScript types provided. For browser usage, bundle with a bundler or use a CDN that supports ESM.","symbol":"RemoteApi","correct":"import { RemoteApi } from 'apipublisher'"},{"note":"ServerApi is for Node-to-Node calls. It has a static method .load() which accepts a URL or Url object.","symbol":"ServerApi","correct":"import { ServerApi } from 'apipublisher'"}],"quickstart":{"code":"import { ApiPublisher } from 'apipublisher';\nimport express from 'express';\n\nconst app = express();\n\nconst myAPI = {\n  greet: async (name) => `Hello, ${name}!`,\n  add: async (a, b) => a + b\n};\n\nconst api = new ApiPublisher(myAPI);\napp.use('/api', api.handle);\n\napp.listen(3000, () => {\n  console.log('Server listening on port 3000');\n});","lang":"typescript","description":"Exposes an async API over HTTP using Express. Note: 'api.handle' must be passed to app.use(), not the API object itself."},"warnings":[{"fix":"Replace `app.use('/api', api)` with `app.use('/api', api.handle)`.","message":"ApiPublisher v1.1.x breaking change: you must pass `api.handle` to `app.use()`, not just `api`.","severity":"breaking","affected_versions":">=1.1.0 <2.0.0"},{"fix":"Use `import` syntax or upgrade to Node >=12 with --experimental-modules for older versions.","message":"ESM-only since v2.0.0; CommonJS require() will fail.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Consider migrating to a library that uses native async/await and standard Promises.","message":"Version 2.1.5 still uses Nodent internally; Nodent is unmaintained and may cause compatibility issues with modern Node.js.","severity":"deprecated","affected_versions":"2.x"},{"fix":"Avoid property names that conflict with Promise or Object prototypes.","message":"Browser RemoteApi automatically provisions nested APIs under the same path; ensure your API object does not have overlapping property names with built-in methods like 'resolve' or 'then'.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use `new URL('http://example.com/api')` if passing an object, or simply a string URL.","message":"ServerApi.load() accepts a URL object with options like 'agent', but the URL must be an instance of the Node URL class; plain strings are also accepted.","severity":"gotcha","affected_versions":">=1.2.0"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Run `npm install apipublisher` and ensure you are using ESM import syntax (e.g., `import { ApiPublisher } from 'apipublisher'`).","cause":"Package not installed or wrong import path.","error":"Cannot find module 'apipublisher'"},{"fix":"Use `app.use('/path', api.handle)`.","cause":"Passing the whole API object to app.use() instead of api.handle.","error":"TypeError: api is not a function"},{"fix":"Wrap the code in an async function: `async function main() { ... }` or use Promises with `.then()`.","cause":"Using 'await' outside an async function in non-ES7 code.","error":"SyntaxError: await is only valid in async function"},{"fix":"Use `import { ... } from 'apipublisher'` or rename file to .cjs.","cause":"Using require() in an ESM context.","error":"ReferenceError: require is not defined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}