You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Node-API is Node.js' native addon API. Bun implements Node-API so that native addons built for Node.js work in Bun without modification or recompilation.
If a native addon crashes or misbehaves in Bun, please open a new issue with a reproduction rather than commenting here.
Counted on Linux. macOS/Windows each have one extra platform-specific todo (73/97, 75.3%).
The node-api todos are concentrated in async_hooks integration, uv_* loop/threadpool semantics, worker-terminate finalization, and fatal-error reporting — see the todoIf entries in test/napi/node-napi-tests/test/node-api/*/do.test.ts for the live list.
Remaining work is behavioral parity in those areas and edge-case compatibility with specific packages, not missing API surface.
async_hooks integration — napi_async_init, napi_async_destroy, napi_make_callback, napi_open_callback_scope, and napi_close_callback_scope all work, but do not emit async_hooks lifecycle events. We don't plan to implement this. Node.js itself marks async_hooks as Experimental and discourages its use: "Please migrate away from this API, if you can. We do not recommend using the createHook, AsyncHook, and executionAsyncResource APIs as they have usability issues, safety risks, and performance implications." Bun implements the stable AsyncLocalStorage API instead, which is what Node recommends migrating to.
Worker termination — finalizer and buffer-callback ordering during Worker.terminate() doesn't fully match Node. Tracked as part of Worker & worker_threads stability tracking issue #15964 alongside other worker_threads stability work.
napi_adjust_external_memory reports to JSC's GC heuristic but does not behave identically to V8.
Node-API is Node.js' native addon API. Bun implements Node-API so that native addons built for Node.js work in Bun without modification or recompilation.
If a native addon crashes or misbehaves in Bun, please open a new issue with a reproduction rather than commenting here.
Status: API surface complete
Every
napi_*andnode_api_*function is implemented and exported. Bun runs Node.js' ownjs-native-apiandnode-apitest suites in CI on every commit (seetest/napi/node-napi-tests/).js-native-api(engine-agnostic core)node-api(Node.js-runtime-specific)Counted on Linux. macOS/Windows each have one extra platform-specific todo (73/97, 75.3%).
The
node-apitodos are concentrated inasync_hooksintegration,uv_*loop/threadpool semantics, worker-terminate finalization, and fatal-error reporting — see thetodoIfentries intest/napi/node-napi-tests/test/node-api/*/do.test.tsfor the live list.Remaining work is behavioral parity in those areas and edge-case compatibility with specific packages, not missing API surface.
Implementation
src/bun.js/bindings/napi.cppnapi_*functions, JSC integrationsrc/napi/napi.zigsrc/bun.js/bindings/v8/src/symbols.txtKnown gaps & caveats
async_hooksintegration —napi_async_init,napi_async_destroy,napi_make_callback,napi_open_callback_scope, andnapi_close_callback_scopeall work, but do not emitasync_hookslifecycle events. We don't plan to implement this. Node.js itself marksasync_hooksas Experimental and discourages its use: "Please migrate away from this API, if you can. We do not recommend using thecreateHook,AsyncHook, andexecutionAsyncResourceAPIs as they have usability issues, safety risks, and performance implications." Bun implements the stableAsyncLocalStorageAPI instead, which is what Node recommends migrating to.uv_*symbols is exported for addons that link against libuv directly. On Linux/macOS, Bun does not run on libuv, souv_default_loop()is not the runtime's event loop — addons must usenapi_get_uv_event_loop(N-API addons using uv_default_loop for uv_async don’t fire callbacks; using napi_get_uv_event_loop fixes it #23192). We don't currently plan to implement all of libuv inside Bun, but we may revisit if enough bug reports show it's needed in practice — tracked in Implement libuv functions #18546.Worker.terminate()doesn't fully match Node. Tracked as part ofWorker&worker_threadsstability tracking issue #15964 alongside otherworker_threadsstability work.napi_adjust_external_memoryreports to JSC's GC heuristic but does not behave identically to V8.Full function list — 156/156 implemented
napi_*napi_acquire_threadsafe_functionnapi_add_async_cleanup_hooknapi_add_env_cleanup_hooknapi_add_finalizernapi_adjust_external_memorynapi_async_destroynapi_async_initnapi_call_functionnapi_call_threadsafe_functionnapi_cancel_async_worknapi_check_object_type_tagnapi_close_callback_scopenapi_close_escapable_handle_scopenapi_close_handle_scopenapi_coerce_to_boolnapi_coerce_to_numbernapi_coerce_to_objectnapi_coerce_to_stringnapi_create_arraynapi_create_array_with_lengthnapi_create_arraybuffernapi_create_async_worknapi_create_bigint_int64napi_create_bigint_uint64napi_create_bigint_wordsnapi_create_buffernapi_create_buffer_copynapi_create_dataviewnapi_create_datenapi_create_doublenapi_create_errornapi_create_externalnapi_create_external_arraybuffernapi_create_external_buffernapi_create_functionnapi_create_int32napi_create_int64napi_create_objectnapi_create_promisenapi_create_range_errornapi_create_referencenapi_create_string_latin1napi_create_string_utf16napi_create_string_utf8napi_create_symbolnapi_create_threadsafe_functionnapi_create_type_errornapi_create_typedarraynapi_create_uint32napi_define_classnapi_define_propertiesnapi_delete_async_worknapi_delete_elementnapi_delete_propertynapi_delete_referencenapi_detach_arraybuffernapi_escape_handlenapi_fatal_errornapi_fatal_exceptionnapi_get_all_property_namesnapi_get_and_clear_last_exceptionnapi_get_array_lengthnapi_get_arraybuffer_infonapi_get_booleannapi_get_buffer_infonapi_get_cb_infonapi_get_dataview_infonapi_get_date_valuenapi_get_elementnapi_get_globalnapi_get_instance_datanapi_get_last_error_infonapi_get_named_propertynapi_get_new_targetnapi_get_node_versionnapi_get_nullnapi_get_propertynapi_get_property_namesnapi_get_prototypenapi_get_reference_valuenapi_get_threadsafe_function_contextnapi_get_typedarray_infonapi_get_undefinednapi_get_uv_event_loopnapi_get_value_bigint_int64napi_get_value_bigint_uint64napi_get_value_bigint_wordsnapi_get_value_boolnapi_get_value_doublenapi_get_value_externalnapi_get_value_int32napi_get_value_int64napi_get_value_string_latin1napi_get_value_string_utf16napi_get_value_string_utf8napi_get_value_uint32napi_get_versionnapi_has_elementnapi_has_named_propertynapi_has_own_propertynapi_has_propertynapi_instanceofnapi_is_arraynapi_is_arraybuffernapi_is_buffernapi_is_dataviewnapi_is_datenapi_is_detached_arraybuffernapi_is_errornapi_is_exception_pendingnapi_is_promisenapi_is_typedarraynapi_make_callbacknapi_module_registernapi_new_instancenapi_object_freezenapi_object_sealnapi_open_callback_scopenapi_open_escapable_handle_scopenapi_open_handle_scopenapi_queue_async_worknapi_ref_threadsafe_functionnapi_reference_refnapi_reference_unrefnapi_reject_deferrednapi_release_threadsafe_functionnapi_remove_async_cleanup_hooknapi_remove_env_cleanup_hooknapi_remove_wrapnapi_resolve_deferrednapi_run_scriptnapi_set_elementnapi_set_instance_datanapi_set_named_propertynapi_set_propertynapi_strict_equalsnapi_thrownapi_throw_errornapi_throw_range_errornapi_throw_type_errornapi_type_tag_objectnapi_typeofnapi_unref_threadsafe_functionnapi_unwrapnapi_wrapnode_api_*node_api_create_buffer_from_arraybuffernode_api_create_external_string_latin1node_api_create_external_string_utf16node_api_create_property_key_latin1node_api_create_property_key_utf16node_api_create_property_key_utf8node_api_create_syntax_errornode_api_get_module_file_namenode_api_post_finalizernode_api_symbol_fornode_api_throw_syntax_errorRelated tracking
worker_threadsstability:Worker&worker_threadsstability tracking issue #15964napi-labeled bugs: issue list