Criando pacote instalável com NPX
Depois de alguns anos trabalhando como programador, independente da linguagem, framework ou nível de senioridade, todos acabam por ter seus próprios “pré-sets” de trabalho, com bibliotecas, estrutura de pastas, configurações, enfim. Pedaços de códigos que muitas das vezes escrevemos ou na grande maioria delas copiamos e colamos, pois, são tão agnósticos ao projeto que não vale a pena o tempo de reescreve-las.
Alguns deixam salvo uma pastinha com esse start, outros criam um repositório no github e clonam toda vez que precisam, e não me entendam mal essas abordagens funcionam, eu mesmo sempre mantive o meu starter pack no github, mas essas formas tem problemas seja perder a pastinha deleta-la sem querer ou ter que formatar o pc ou no caso do github esquecer de trocar o remote e subir varias alteração nos seus arquivos, falo por experiência própria rsrsrs.
Faz um tempo que estava criando um protótipo, por ser apenas um teste utilizei o Create React App, que é basicamente um starter pack do reactjs, e me deparei com o comando:
npx create-react-app my-app
Não que fosse um comando que nunca tinha visto, mas pensei “Sera se tem como eu criar meu próprio create-react-app?”, fiquei obcecado, revirei a internet procurando como fazer um pacote “instável”, e depois de muita pesquisa e muitos testes consegui 🙌🏾 .
É muito mais vantajoso criar um pacote que possa ser instalado via npx.
- Você não precisa clonar o projeto todas às vezes
- Não corre o risco de “sujar” seu pre-set em querer
- Pode compartilhar de um jeito simples
- Não corre o risco de perder seu precioso starter pack
- Além de ser muito legal 😬.
Como?
Você não achou que eu ia contar toda essa história e não ia te contar como fazer isso né?
Existem algumas maneiras de se fazer um pacote que possa ser instalado, vou explicar a que considero mais simples tanto para manutenção quanto atualização.
Conta NPM 🧐
Primeiro de tudo e mais importante é ter uma conta no https://www.npmjs.com/, você pode cria-la tanto pelo site quanto por linha de comando, vou explicar o caminho pela linha de comando, mas pelo site é a mesma coisa.
Com o node instalado abra o terminal e digite:
npm adduser
No momento esse comando ainda funciona, mas logo sera dividido em login
e register
.
- Digite seu Username
- Depois sua senha
- Seu email
- Por fim o código OTP (um código de 8 dígitos enviado para seu email).
Digite o comando:
npm whoami
Se aparecer seu Username …
Parabéns!! Você acabou de criar uma conta no NPMjs

Código 🤩
Crie uma pasta para seu pacote, criei a pasta my-package-teste como exemplo.
Abra sua pasta no terminal e digite o comando:
npm init -y
Um arquivo package.json vai ser criado:
// my-package/package.json
{
"name": "my-package-teste",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Vamos fazer algumas alterações
- adicionar a linha:
"main": "/bin/index.js"
- Adicionar a linha:
"bin": "./bin/index.js"
Pronto! Essa é a configuração básica, claro que é possível configurar muito mais coisas, você pode ver todas as propriedades aqui https://docs.npmjs.com/cli/v9/configuring-npm/package-json, ou as configurações que uso aqui https://gist.github.com/alexmadeira/e055782de0a6f97a9e2bdbaafe553326
Bom nosso arquivo package.json
vai ficar assim.
// my-package/package.json
{
"name": "my-package-teste",
"version": "1.0.0",
"description": "",
"main": "/bin/index.js",
"bin": "./bin/index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Agora crie uma pasta bin
e dentro dela um arquivo index.js
.
Essa é a estrutura do nosso pequeno pacote 🥰.

Abra o arquivo index.js
e adicione #!/usr/bin/env node
na primeira linha
Adicione um console.log("Olá mundãooo")
// my-package/index.js
#!/usr/bin/env node
console.log("Olá mundãooo")
Ai você me pergunta:
— Lapidem é só isso?
Ai eu te respondo:
— Caaaalma caaaalma
De volta a linha de comando
Voltando para linha de comando digite o comando:
npm publish
Lembrando que o nome do seu pacote tem que ser único
Se tudo deu certo você vai ver algo parecido com isso:

Se quiser uma confirmação visual, você pode entrar no site do npm, entrar na sua conta depois ir até packages
Hora de testar 🥳
Feche todas as instâncias do terminal só para limpar qualquer cache que possa existir, abra um novo terminar e digite o comando:
npx my-package-teste@latest
Lembrando troque “my-package-teste” pelo nome do seu pacote.
O sufixo @latest é para forçar a instalação da última versão do seu pacote
Se o seu “Olá mundãooo” apareceu no terminal, você esta pronto para o próximo passo
Criando meu Starter pack
Agora você vai precisar que seu amado starter pack esteja no github.
-
Adicione o pacote
child_process
ao projetoNo terminal, na pasta do my-package-teste digite o comando:
npm install child_process
-
Vamos alterar o nosso arquivo
bin/index.js
para:#!/usr/bin/env node const { execSync } = require('child_process') // importa o pacote child_process para conseguir executar comandos const repoName = process.argv[2] // guarda o nome para o repositório const gitCheckoutCommand = `git clone https://github.com/alexmadeira/nextJs-boilerplate ${repoName}` // comando de clonagem git const installDespCommand = `cd ${repoName} && npm install` // Comando para entrar na pasta do repositório e instalar as dependencias const removeGitRemoteCommand = `cd ${repoName} && git remote remove origin` // Comando para entrar na pasta do repositório e remover o vinculo com git //função para executar um comando enviado const runCommand = command => { try { execSync(`${command}`, { stdio: 'inherit' }) } catch (error) { console.error(`Falha na execução ${command}`, error) return false } return true } console.log(`Clonando para ${repoName}`) const checkout = runCommand(gitCheckoutCommand) // executa o comando de Checkout if (!checkout) process.exit() // caso algo de errado parra a execução console.log(`Instalando dependências`) const installedDeps = runCommand(installDespCommand) // executa o comand que instala as dependencias if (!installedDeps) process.exit()// caso algo de errado parra a execução console.log(`Removendo arquivos de instalação`) const removeGitRemote = runCommand(removeGitRemoteCommand)// executa o comand que remove a referencia do repositório if (!removeGitRemote) process.exit()// caso algo de errado parra a execução
Na variável
gitCheckoutCommand
você deve colocar o link do repositório dos seus arquivos de configuração. -
Agora antes de publicar voltamos para o arquivo
package.json
e mudamos a versão// my-package/package.json { "name": "my-package-teste", "version": "2.0.0", "description": "", "main": "/bin/index.js", "bin": "./bin/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
Sempre que for atualizar seu pacote, é necessário mudar a versão (é uma boa prática utilizar o sistema de versionamento semântico talvez eu faça um post sobre o assunto)
-
Agora sim, pode voltar para o terminar e digitar o comando
npm publish
Agora bastar usar o npx instalar seu starter pack
npx my-package-teste@latest my-app
A pasta com seus arquivos vai ser copiada para pasta my-app
.
Conclusão
Esse foi um exemplo de um pacote que criei para startar uma aplicação em nextjs, mas serve para qualquer tipo de projeto qualquer linguagem.
A vantagem de deixar separado é que você pode fazer atualizações nos seus arquivos sem necessariamente mudar a versão do pacote, você também pode adicionar novos comandos e novas funcionalidades como mostrar seu nome, informações de contato, etc., antes do da instalação ou ao final mostrar um passo a passo de como iniciar o projeto.
Caso queira ver o meu pacote nextjs que utilizo nos meus projetos basta usar o comando:
npx create-boilerplate-next-app@latest my-app
É isso obrigado pelo seu tempo, e parabéns por ler até o final, sei que ficou meio grande, mas não queria deixar nenhuma duvidas e mesmo assim sei que talvez apareçam muitas.
Vlw Flw ... 👋🏾
