Package Structure
Understanding the structure of your package is essential for effective development and maintenance. PackShip creates a well-organized project structure based on your choices during initialization.
Project Types
PackShip supports multiple project types, each with its own recommended structure. The structure varies based on your language choice (TypeScript or JavaScript) and project type.
TypeScript React Package
A TypeScript React package is structured to support component development with type safety:
my-package/ ├── src/ │ ├── index.tsx # Main entry point │ ├── declaration.d.ts # TypeScript declarations │ └── internal/ # (Optional) Internal components │ └── index.tsx ├── types/ │ └── index.ts # Type definitions ├── styles/ # (Optional) CSS styles │ └── style.css ├── dist/ # Compiled output (created after build) ├── package.json # Package configuration ├── tsconfig.json # TypeScript configuration ├── webpack.config.js # (Optional) Webpack configuration ├── babel.config.json # Babel configuration ├── postcss.config.js # (Optional) PostCSS configuration ├── .eslintrc.json # (Optional) ESLint configuration ├── .gitignore # Git ignore file ├── .npmignore # (Optional) npm ignore file ├── README.md # (Optional) Documentation ├── LICENSE.md # (Optional) License information └── CODE_OF_CONDUCT.md # (Optional) Code of conduct
TypeScript Node.js Package
A TypeScript Node.js package is structured for server-side development:
my-package/ ├── src/ │ ├── index.ts # Main entry point │ ├── declaration.d.ts # TypeScript declarations │ └── internal/ # (Optional) Internal modules │ └── index.ts ├── types/ │ └── index.ts # Type definitions ├── dist/ # Compiled output (created after build) ├── package.json # Package configuration ├── tsconfig.json # TypeScript configuration ├── webpack.config.js # (Optional) Webpack configuration ├── .eslintrc.json # (Optional) ESLint configuration ├── .gitignore # Git ignore file ├── .npmignore # (Optional) npm ignore file ├── README.md # (Optional) Documentation ├── LICENSE.md # (Optional) License information └── CODE_OF_CONDUCT.md # (Optional) Code of conduct
JavaScript React Package
A JavaScript React package is structured for component development without TypeScript:
my-package/ ├── src/ │ ├── index.jsx # Main entry point │ └── internal/ # (Optional) Internal components │ └── index.jsx ├── styles/ # (Optional) CSS styles │ └── style.css ├── dist/ # Compiled output (created after build) ├── package.json # Package configuration ├── webpack.config.js # (Optional) Webpack configuration ├── babel.config.json # Babel configuration ├── postcss.config.js # (Optional) PostCSS configuration ├── .eslintrc.json # (Optional) ESLint configuration ├── .gitignore # Git ignore file ├── .npmignore # (Optional) npm ignore file ├── README.md # (Optional) Documentation ├── LICENSE.md # (Optional) License information └── CODE_OF_CONDUCT.md # (Optional) Code of conduct
JavaScript Node.js Package
A JavaScript Node.js package is structured for server-side development without TypeScript:
my-package/ ├── src/ │ ├── index.js # Main entry point │ └── internal/ # (Optional) Internal modules │ └── index.js ├── dist/ # Compiled output (created after build) ├── package.json # Package configuration ├── webpack.config.js # (Optional) Webpack configuration ├── .eslintrc.json # (Optional) ESLint configuration ├── .gitignore # Git ignore file ├── .npmignore # (Optional) npm ignore file ├── README.md # (Optional) Documentation ├── LICENSE.md # (Optional) License information └── CODE_OF_CONDUCT.md # (Optional) Code of conduct
Vanilla JavaScript Package
A Vanilla JavaScript package is structured for browser-based utilities without framework dependencies:
my-package/ ├── src/ │ ├── index.js # Main entry point │ └── internal/ # (Optional) Internal utilities │ └── index.js ├── styles/ # (Optional) CSS styles │ └── style.css ├── dist/ # Compiled output (created after build) ├── package.json # Package configuration ├── webpack.config.js # (Optional) Webpack configuration ├── postcss.config.js # (Optional) PostCSS configuration ├── .eslintrc.json # (Optional) ESLint configuration ├── .gitignore # Git ignore file ├── .npmignore # (Optional) npm ignore file ├── README.md # (Optional) Documentation ├── LICENSE.md # (Optional) License information └── CODE_OF_CONDUCT.md # (Optional) Code of conduct
Key Files and Directories
Entry Points
The entry point is the main file that exports your package's functionality:
src/index.tsx
orsrc/index.jsx
: Main entry point for React packagessrc/index.ts
orsrc/index.js
: Main entry point for Node.js and Vanilla JS packages
Example of a TypeScript React entry point:
// src/index.tsx
import MyComponent from './components/MyComponent';
import MyOtherComponent from './components/MyOtherComponent';
// Export components
export { MyComponent, MyOtherComponent };
// Default export
export default { MyComponent, MyOtherComponent };
Type Definitions
TypeScript packages include type definitions to provide type information:
types/index.ts
: Contains shared type definitionssrc/declaration.d.ts
: Contains module declarations for non-TypeScript files
Example of type definitions:
// types/index.ts
export interface ComponentProps {
className?: string;
children?: React.ReactNode;
onClick?: () => void;
}
export type Theme = 'light' | 'dark' | 'system';
Configuration Files
PackShip generates several configuration files based on your choices:
package.json
: Defines package metadata, dependencies, and scriptstsconfig.json
: Configures TypeScript compiler optionswebpack.config.js
: Configures bundling options (if Webpack is selected)babel.config.json
: Configures Babel for transpilation (for React projects)postcss.config.js
: Configures PostCSS for CSS processing (if selected).eslintrc.json
: Configures ESLint for code linting (if selected)
package.json
The package.json
file contains important metadata and configuration:
{
"name": "my-package",
"version": "0.1.0",
"description": "My awesome package",
"main": "dist/index.js",
"module": "dist/index.mjs",
"type": "module",
"scripts": {
"test": "echo 'Error: no test specified' && exit 1",
"build": "tsc && npm run build-babel && npm run build-webpack",
"build-babel": "babel src --out-dir dist --presets=@babel/preset-react,@babel/preset-env",
"build-webpack": "webpack --config webpack.config.js",
"lint": "eslint .",
"packship:publish": "packship publish"
},
"keywords": [],
"author": {
"name": "Your Name",
"email": "your.email@example.com"
},
"license": "MIT",
"_packshipInitialized": true,
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/cli": "^7.10.5",
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/preset-react": "^7.23.3",
"@babel/preset-typescript": "^7.24.7",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"ts-loader": "^9.5.1",
"typescript": "^4.9.5",
"webpack": "^5.0.0",
"webpack-cli": "^5.1.4",
"eslint": "^7.32.0",
"eslint-plugin-react": "^7.24.0",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"autoprefixer": "^10.3.1",
"postcss": "^8.4.5"
}
}
The _packshipInitialized
property is added to your package.json to indicate that the package was initialized with PackShip.
Customizing Your Project Structure
While PackShip provides a solid foundation, you can customize your project structure to fit your specific needs:
Adding Directories
src/components/
: For React componentssrc/hooks/
: For React hookssrc/utils/
: For utility functionssrc/services/
: For service modulessrc/constants/
: For constant valuestests/
: For test files
Recommended Practices
- Keep related files together in feature-based directories
- Use clear, consistent naming conventions
- Export public APIs only from the main entry point
- Use the internal directory for components not meant for public consumption
- Keep configuration files at the root level
While you can customize your project structure, following the PackShip conventions makes it easier to use the built-in tools and workflows.