Develop a Node.js addon module in C# with .NET Native AOT
About .NET Native AOT
AOT compiled modules load more quickly and do not have any runtime dependency .NET. However, .NET Native AOT has some limitations, so you should understand the implications before starting on this path. Some of the considerations include:
- .NET 8 SDK or later is required at build time. (Not at run time.)
- AOT binaries are much larger: at least 4-10 MB depending on the platform.
- AOT code can only call other native code. That may include other .NET Native AOT assemblies, but NOT any managed .NET assemblies, because the .NET runtime is not loaded.
- No dynamic loading, reflection, or runtime code-generation is possible.
- Some .NET APIs and libraries are not compatible with AOT. For more details, see https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/
Enabling AOT in a C# project
To set up a project for building a Node.js addon module using C# Native AOT, start with the steps for building a regular .NET module.
Then enable .NET Native AOT compilation in the C# project:
- Make sure the
TargetFramework
is .NET 8 or later. - Add the publishing properties to the project file:
xml
<PublishAot>true</PublishAot>
<PublishNodeModule>true</PublishNodeModule>
<PublishDir>bin</PublishDir>
<PackNpmPackage>true</PackNpmPackage>
<PackageOutputPath>pkg</PackageOutputPath>
- Publish the project to produce the native module (with
.node
extension) and npm package (with.tgz
extension):
shell
dotnet publish
A native module does not depend on the node-api-dotnet
package, so it can be removed from the JavaScript project's package.json
. Then update the JavaScript code to require()
the .NET AOT module directly. Be sure to reference the published .node
file location, which might be different from the built .dll
location.
JavaScript
const ExampleModule = require('./bin/ExampleModule');
JavaScript
import ExampleModule from './bin/ExampleModule';