diff --git a/.github/workflows/test-nitro-cli.yml b/.github/workflows/test-nitro-cli.yml
index 1a8eb2e9..aed939ec 100644
--- a/.github/workflows/test-nitro-cli.yml
+++ b/.github/workflows/test-nitro-cli.yml
@@ -70,7 +70,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
- pm: ['bun', 'yarn']
+ pm: ['bun', 'yarn', 'pnpm']
package-type: ['module', 'view']
env:
@@ -83,8 +83,14 @@ jobs:
git config --global user.name "GitHub Actions Bot"
git config --global user.email "actions@github.com"
+ - name: Setup pnpm
+ if: matrix.pm == 'pnpm'
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
- if: matrix.pm == 'yarn'
+ if: matrix.pm == 'yarn' || matrix.pm == 'pnpm'
uses: actions/setup-node@v4
with:
node-version: 22.x
@@ -113,8 +119,14 @@ jobs:
- name: Generate ${{ matrix.package-type }} with ${{ matrix.pm }}
continue-on-error: false
+ if: matrix.pm != 'pnpm'
run: ${{ matrix.pm }} create nitro-module test-${{ matrix.package-type }} --skip-install --ci
+ - name: Generate ${{ matrix.package-type }} with ${{ matrix.pm }}
+ continue-on-error: false
+ if: matrix.pm == 'pnpm'
+ run: create-nitro-module test-${{ matrix.package-type }} --skip-install --ci
+
- name: Verify generated package structure
run: |
PACKAGE_DIR="react-native-test-${{ matrix.package-type }}"
@@ -182,7 +194,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
- pm: ['bun', 'yarn']
+ pm: ['bun', 'yarn', 'pnpm']
package-type: ['module', 'view']
mode: ['Debug', 'Release']
env:
@@ -209,8 +221,14 @@ jobs:
ruby-version: '3.2'
bundler-cache: true
+ - name: Setup pnpm
+ if: matrix.pm == 'pnpm'
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
- if: matrix.pm == 'yarn'
+ if: matrix.pm == 'yarn' || matrix.pm == 'pnpm'
uses: actions/setup-node@v4
with:
node-version: 22.x
@@ -272,7 +290,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- pm: ['bun', 'yarn']
+ pm: ['bun', 'yarn', 'pnpm']
package-type: ['module', 'view']
mode: ['Debug', 'Release']
env:
@@ -293,8 +311,14 @@ jobs:
echo "Package structure:"
find . -type f -name "*.json" -o -name "*.js" -o -name "*.ts" | head -20
+ - name: Setup pnpm
+ if: matrix.pm == 'pnpm'
+ uses: pnpm/action-setup@v4
+ with:
+ version: 10
+
- name: Setup Node.js
- if: matrix.pm == 'yarn'
+ if: matrix.pm == 'yarn' || matrix.pm == 'pnpm'
uses: actions/setup-node@v4
with:
node-version: 22.x
diff --git a/README.md b/README.md
index d65c5bbe..4a248f79 100644
--- a/README.md
+++ b/README.md
@@ -33,6 +33,9 @@ bun create nitro-module@latest my-nitro-module
# Using yarn
yarn create nitro-module@latest my-nitro-module
+# Using pnpm
+pnpm create nitro-module@latest my-nitro-module
+
# Using npx
npx create-nitro-module@latest my-nitro-module
```
diff --git a/commitlint.config.cjs b/commitlint.config.cjs
index 3e16e7f1..186619e5 100644
--- a/commitlint.config.cjs
+++ b/commitlint.config.cjs
@@ -1,3 +1,6 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
+ rules: {
+ 'footer-max-line-length': [0, 'always'],
+ },
}
diff --git a/docs/docs/commands.md b/docs/docs/commands.md
index 5eb9005f..853e7b27 100644
--- a/docs/docs/commands.md
+++ b/docs/docs/commands.md
@@ -45,6 +45,11 @@ Options:
yarn create nitro-module@latest my-awesome-module
```
+
+ ```bash
+ pnpm create nitro-module@latest my-awesome-module
+ ```
+
For additional support, please [open an issue](https://github.com/patrickkabwe/create-nitro-module/issues) on our GitHub repository.
diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md
index a7102267..9adc3889 100644
--- a/docs/docs/troubleshooting.md
+++ b/docs/docs/troubleshooting.md
@@ -6,81 +6,78 @@ This section provides solutions to common issues you might encounter while using
1. **Pod Install Fails**
- If you encounter issues during `pod install`, try the following steps:
+ If you encounter issues during `pod install`, try the following steps:
- ```bash
- cd yourpackage/ios
- pod deintegrate
- pod install
- ```
+ ```bash
+ cd yourpackage/ios
+ pod deintegrate
+ pod install
+ ```
2. **Missing Header Files**
- If Xcode reports missing header files, follow these steps:
+ If Xcode reports missing header files, follow these steps:
- - Clean the build folder in Xcode (`Product` -> `Clean Build Folder`).
- - Ensure all native dependencies are properly linked.
- - Rebuild the project.
+ - Clean the build folder in Xcode (`Product` -> `Clean Build Folder`).
+ - Ensure all native dependencies are properly linked.
+ - Rebuild the project.
### Android Build Issues
1. **Gradle Sync Failed**
- If Gradle sync fails, try cleaning and rebuilding the project:
+ If Gradle sync fails, try cleaning and rebuilding the project:
- ```bash
- cd yourpackage/android
- ./gradlew clean
- ./gradlew build
- ```
+ ```bash
+ cd yourpackage/android
+ ./gradlew clean
+ ./gradlew build
+ ```
2. **Missing Dependencies**
- If you encounter missing dependencies, check the following:
+ If you encounter missing dependencies, check the following:
- - Ensure `build.gradle` contains the correct dependencies.
- - Sync the project with Gradle files.
- - Invalidate caches and restart Android Studio.
+ - Ensure `build.gradle` contains the correct dependencies.
+ - Sync the project with Gradle files.
+ - Invalidate caches and restart Android Studio.
### General Issues
1. **Error Invalid Version: latest**
- If you encounter an invalid version error, this is due to an issue with the CLI: See issue: [Invalid Version: latest](https://github.com/react-native-community/cli/issues/2486)
+ If you encounter an invalid version error, this is due to an issue with the CLI: See issue: [Invalid Version: latest](https://github.com/react-native-community/cli/issues/2486)
- ```bash
- ✖ Failed to create nitro module: Command failed: bunx -y @react-native-community/cli@latest init TestToSpeechExample --directory path/react-native-module/example --skip-install
- Resolving dependencies
- Resolved, downloaded and extracted [2]
- Saved lockfile
- error Invalid Version: latest.
- ```
+ ```bash
+ ✖ Failed to create nitro module: Command failed: bunx -y @react-native-community/cli@latest init TestToSpeechExample --directory path/react-native-module/example --skip-install
+ Resolving dependencies
+ Resolved, downloaded and extracted [2]
+ Saved lockfile
+ error Invalid Version: latest.
+ ```
- To resolve this issue, use the following command: keep trying until it works.
+ To resolve this issue, use the following command: keep trying until it works.
-2. **Module Not Found**
+2. **Command Not Found**
- If a module is not found, ensure it is properly installed and linked:
+ If a CLI command is not recognized, ensure the CLI is installed globally:
- ```bash
- npm install
- npx react-native link
- ```
+ ```bash
+ npm install -g create-nitro-module@latest
+ # or
+ pnpm add -g create-nitro-module@latest
+ # or
+ yarn global add create-nitro-module@latest
+ # or
+ bun i -g create-nitro-module@latest
+ ```
-3. **Command Not Found**
+3. **Permission Denied**
- If a CLI command is not recognized, ensure the CLI is installed globally:
+ If you encounter permission issues, try running the command with `sudo`:
- ```bash
- npm install -g create-nitro-module
- ```
-
-4. **Permission Denied**
-
- If you encounter permission issues, try running the command with `sudo`:
-
- ```bash
- sudo
- ```
+ ```bash
+ sudo
+ ```
For additional support, please [open an issue](https://github.com/patrickkabwe/create-nitro-module/issues) on our GitHub repository.
diff --git a/docs/docs/usage/create-a-nitro-module.md b/docs/docs/usage/create-a-nitro-module.md
index 147e2b17..3b266845 100644
--- a/docs/docs/usage/create-a-nitro-module.md
+++ b/docs/docs/usage/create-a-nitro-module.md
@@ -29,6 +29,11 @@ To create a Nitro Module along with an example app, use the following command. T
yarn create nitro-module@latest my-awesome-module
```
+
+ ```bash
+ pnpm create nitro-module@latest my-awesome-module
+ ```
+
## Without example app
@@ -51,6 +56,11 @@ If you prefer to create a Nitro Module without an example app, use the following
yarn create nitro-module@latest my-awesome-module --skip-example
```
+
+ ```bash
+ pnpm create nitro-module@latest my-awesome-module --skip-example
+ ```
+
The `--skip-example` flag indicates that the example app should be skipped.
@@ -75,6 +85,11 @@ If you prefer to create a Nitro Module within a specific directory, use the foll
yarn create nitro-module@latest my-awesome-module --module-dir packages
```
+
+ ```bash
+ pnpm create nitro-module@latest my-awesome-module --module-dir packages
+ ```
+
This command will create a Nitro Module within the `packages` directory as shown in the example above.
diff --git a/docs/docs/usage/installation.md b/docs/docs/usage/installation.md
index 3f7e0c1c..579c2a1d 100644
--- a/docs/docs/usage/installation.md
+++ b/docs/docs/usage/installation.md
@@ -23,6 +23,12 @@ bun install -g create-nitro-module
yarn global add create-nitro-module
```
+### Using PNPM
+
+```bash
+pnpm add -g create-nitro-module
+```
+
### Using NPM
```bash
diff --git a/package.json b/package.json
index 641ee74f..48f05248 100644
--- a/package.json
+++ b/package.json
@@ -37,8 +37,7 @@
],
"license": "MIT",
"bin": {
- "create-nitro-module": "./lib/cli/index.js",
- "nitro-module": "./lib/cli/index.js"
+ "create-nitro-module": "./lib/cli/index.js"
},
"repository": {
"type": "git",
diff --git a/src/cli/create.ts b/src/cli/create.ts
index 0c83926b..bf9e5a1a 100644
--- a/src/cli/create.ts
+++ b/src/cli/create.ts
@@ -144,7 +144,7 @@ const getUserAnswers = async (
platforms: [SupportedPlatform.IOS, SupportedPlatform.ANDROID],
packageType: Nitro.Module,
langs: [SupportedLang.SWIFT, SupportedLang.KOTLIN],
- pm: usedPm || 'bun',
+ pm: usedPm || 'pnpm',
}
}
@@ -250,6 +250,10 @@ const getUserAnswers = async (
label: 'npm',
value: 'npm',
},
+ {
+ label: 'pnpm',
+ value: 'pnpm',
+ },
],
})
},
diff --git a/src/generate-nitro-package.ts b/src/generate-nitro-package.ts
index e53b9838..72977879 100644
--- a/src/generate-nitro-package.ts
+++ b/src/generate-nitro-package.ts
@@ -142,6 +142,8 @@ export class NitroModuleFactory {
let script = `${this.config.pm} --cwd example pod`
if (this.config.pm === 'npm') {
script = `${this.config.pm} --prefix example run pod`
+ } else if (this.config.pm === 'pnpm') {
+ script = `pnpm --filter ./example pod`
}
return script
}
@@ -187,6 +189,23 @@ export class NitroModuleFactory {
cwd: this.config.cwd,
})
await execAsync('corepack disable', { cwd: this.config.cwd })
+ } else if (this.config.pm === 'pnpm') {
+ const workspaceDirs = ['example']
+ const yamlContent = `packages:\n${workspaceDirs.map(d => ` - ${d}`).join('\n')}\n`
+
+ const WORKSPACE_FILENAME = 'pnpm-workspace.yaml'
+ await writeFile(
+ path.join(this.config.cwd, WORKSPACE_FILENAME),
+ yamlContent,
+ { encoding: 'utf8' }
+ )
+ const NPMRC_FILENAME = '.npmrc'
+ await writeFile(
+ path.join(this.config.cwd, NPMRC_FILENAME),
+ 'node-linker=hoisted',
+ { encoding: 'utf8' }
+ )
+ delete newWorkspacePackageJsonFile.workspaces
}
if (skipExample) {
@@ -206,9 +225,9 @@ export class NitroModuleFactory {
const replacements = {
[JS_PACKAGE_NAME_TAG]: this.config.finalPackageName,
$$command$$:
- this.config.pm === 'bun' || this.config.pm === 'yarn'
- ? `${this.config.pm} add`
- : 'npm install',
+ this.config.pm === 'npm'
+ ? 'npm install'
+ : `${this.config.pm} add`,
[DESCRIPTION_TAG]: this.config.description,
[AUTHOR_TAG]: getGitUserInfo().name,
[LICENSE_YEAR_TAG]: new Date().getFullYear().toString(),
@@ -257,7 +276,12 @@ export class NitroModuleFactory {
}
private async createExampleApp() {
- const packageManager = this.config.pm === 'bun' ? 'bunx' : 'npx -y'
+ const packageManager =
+ this.config.pm === 'bun'
+ ? 'bunx'
+ : this.config.pm === 'pnpm'
+ ? 'pnpx'
+ : 'npx -y'
const reactNativeVersion =
templatePackageJson.devDependencies['react-native']
@@ -346,9 +370,9 @@ export class NitroModuleFactory {
replacements,
})
- await writeFile(reactNativeConfigPath, reactNativeConfig, {
- encoding: 'utf8',
- })
+ // await writeFile(reactNativeConfigPath, reactNativeConfig, {
+ // encoding: 'utf8',
+ // })
// Setup metro.config.js
const metroConfigPath = path.join(
this.config.cwd,
@@ -356,7 +380,7 @@ export class NitroModuleFactory {
'metro.config.js'
)
- await writeFile(metroConfigPath, metroConfig, { encoding: 'utf8' })
+ // await writeFile(metroConfigPath, metroConfig, { encoding: 'utf8' })
// Setup babel.config.js
const babelConfigPath = path.join(
@@ -365,7 +389,7 @@ export class NitroModuleFactory {
'babel.config.js'
)
- await writeFile(babelConfigPath, babelConfig, { encoding: 'utf8' })
+ // await writeFile(babelConfigPath, babelConfig, { encoding: 'utf8' })
// Setup tsconfig.json
const tsConfigPath = path.join(
@@ -374,11 +398,11 @@ export class NitroModuleFactory {
'tsconfig.json'
)
- await writeFile(
- tsConfigPath,
- exampleTsConfig(this.config.finalPackageName),
- { encoding: 'utf8' }
- )
+ // await writeFile(
+ // tsConfigPath,
+ // exampleTsConfig(this.config.finalPackageName),
+ // { encoding: 'utf8' }
+ // )
const androidSettingsGradlePath = path.join(
this.config.cwd,
@@ -416,12 +440,35 @@ export class NitroModuleFactory {
'hermesCommand = "$rootDir/../../node_modules/react-native/sdks/hermesc/%OS-BIN%/hermesc"',
}
- const toWrite = await replacePlaceholder({
+ const androidBuildGradleData = await replacePlaceholder({
data: androidBuildGradle,
replacements: gradleReplacements,
})
- await writeFile(androidBuildGradlePath, toWrite, { encoding: 'utf8' })
+ // await writeFile(androidBuildGradlePath, androidBuildGradleData, { encoding: 'utf8' })
+
+ const filesToWrite = [
+ { saveTo: reactNativeConfigPath, data: reactNativeConfig },
+ { saveTo: metroConfigPath, data: metroConfig },
+ { saveTo: babelConfigPath, data: babelConfig },
+ {
+ saveTo: tsConfigPath,
+ data: exampleTsConfig(this.config.finalPackageName),
+ },
+ {
+ saveTo: androidSettingsGradlePath,
+ data: androidSettingsGradleCode(
+ toPascalCase(this.config.packageName)
+ ),
+ },
+ { saveTo: androidBuildGradlePath, data: androidBuildGradleData },
+ ]
+ await Promise.all(
+ filesToWrite.map(async item => {
+ const { saveTo, data } = item
+ await writeFile(saveTo, data, { encoding: 'utf8' })
+ })
+ )
for (const folder of foldersToRemoveFromExampleApp) {
await rm(path.join(this.config.cwd, 'example', folder), {
diff --git a/src/types.ts b/src/types.ts
index 3212fec1..b9fec1cb 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,4 +1,5 @@
import * as p from '@clack/prompts'
+import { detectPackageManager } from './utils'
export interface UserAnswers {
packageName: string
@@ -33,7 +34,10 @@ export type CreateModuleOptions = {
skipInstall?: boolean
}
-export type PackageManager = 'bun' | 'yarn' | 'npm'
+export type PackageManager = Exclude<
+ ReturnType,
+ undefined
+>
export enum Nitro {
Module = 'module',
diff --git a/src/utils.ts b/src/utils.ts
index bbd5f4a0..d9115b8c 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -209,6 +209,7 @@ export const detectPackageManager = () => {
if (userAgent.startsWith('npm')) return 'npm'
if (userAgent.startsWith('yarn')) return 'yarn'
if (userAgent.startsWith('bun')) return 'bun'
+ if (userAgent.startsWith('pnpm')) return 'pnpm'
return 'bun'
}