Skip to main content

Create a library

A library packages native modules and components so that other apps can install them with npm. The CLI creates one for the desktop:

npx react-native create-library AwesomeStorage # a Rust module
npx react-native create-library AwesomeStorage --type cpp # a C++ module
OptionDescription
--type <rust|cpp>The native language. Defaults to rust.
--directory <path>Where to create the library. Defaults to the name.
--module-name <name>The native TurboModule name, in PascalCase.
--package-name <name>The npm package name. Defaults to react-native-awesome-storage.

Layout​

react-native-awesome-storage/
├── package.json
├── react-native.config.js
├── src/
│ ├── NativeAwesomeStorage.ts # the specification
│ └── index.ts # the JavaScript API
└── desktop/
├── Cargo.toml
├── build.rs
└── src/lib.rs # the implementation

The specification uses React Native's public TurboModuleRegistry API and TypeScript, so the same file also works for iOS and Android implementations. The JavaScript lives in src/, and everything native for desktop in desktop/.

package.json and the Codegen configuration​

package.json
{
"name": "react-native-awesome-storage",
"version": "0.1.0",
"main": "src/index.ts",
"files": ["src", "desktop", "react-native.config.js", "README.md"],
"codegenConfig": {
"name": "RNAwesomeStorageModuleSpec",
"type": "modules",
"jsSrcsDir": "src"
},
"peerDependencies": { "react-native": ">=0.76" }
}

codegenConfig is React Native's, and is what tells Codegen where the specifications are. Set type to components for a library with host components, or all for both.

The desktop platform entry​

react-native.config.js tells autolinking how to build the desktop side:

react-native.config.js
module.exports = {
dependency: {
platforms: {
desktop: { crate: 'rn-gpui-awesome-storage' },
},
},
};

The crate is in desktop/, and autolinking adds it to the app. It registers its modules in a function called rn_gpui_register:

desktop/src/lib.rs
rn_gpui_module::include_specs!();

pub fn rn_gpui_register() {
rn_gpui_module::register(native_awesome_storage_module::<AwesomeStorage>());
}

The library's Cargo.toml names core's crates by version, as in any Rust module:

desktop/Cargo.toml
[dependencies]
rn-gpui-module = "0.1"

[build-dependencies]
rn-gpui-module-build = "0.1"

See Autolinking for every key.

Adding desktop to a library that supports iOS and Android​

You do not need a new library. Add a desktop/ folder and a platforms.desktop entry to the react-native.config.js you already have, next to the ios and android entries. The specification and the JavaScript are shared, and only the native implementation is new.

Testing​

Test the JavaScript API with your usual unit tests. To test the native side, run the library in an app and drive it with the end-to-end test driver from @react-native-gpui/testing. See Testing.

Publishing​

Publish the package to npm like any other. Because the Rust crates and the C++ sources are part of the package (files lists desktop), the app that installs it builds the native code with its own toolchain. An app picks the library up with autolinking, so users need no setup beyond installing it.