SHOPin Logo
Skip to main documentation content

Other workspaces

Guidance for extending the SHOPin storefront accelerator with new workspace packages under apps/*, core/*, integrations/*, config/*, and demo/*. Root package.json workspaces is the full list if your clone adds other globs.


When to add

Apps (apps/) — A new deployable only when you need a separate UI, lifecycle, or scaling boundary from apps/presentation, apps/bff, or other existing apps (e.g. Storybook, Typedoc under the same folder).

Core (core/) — Shared libraries: types/contracts, cross-app logic, tooling configs, integrations-agnostic utilities. Prefer extending @core/contracts or an existing core/* package before adding a parallel layer.

Config (config/) — Shared constants, enums, and data imported across apps (e.g. config/constants).

Integrations (integrations/) — Nest modules and clients wired into the BFF for a commerce or CMS backend (e.g. integrations/commercetools-api, integrations/contentful-api). New provider or a clear split of an existing one; see Add integration.

Demo (demo/) — Non-production helpers (e.g. data-source switching in dev). Remove demo functionality when you drop that surface area for production.


Layout and naming

Put the package under the correct top-level directory so it matches a workspaces glob and Turborepo still resolves the graph.

Typical library package (e.g. under core/, config/, integrations/):

your-package/
├── dist/                 # build output (gitignored)
├── src/
├── .gitignore
├── .lintstagedrc
├── eslint.config.js      # or eslint.config.mjs — match siblings
├── package.json
├── prettier.config.js
├── README.md
├── tsconfig.json
└── (optional) turbo.json # only if this package defines extra Turbo tasks

Replace your-package/ with the real path (e.g. core/my-lib, config/constants, integrations/my-api).

Register the name in that package’s package.json using the repo convention: @core/…, @config/…, @integrations/…, @apps/…, @demo/… as appropriate.


package.json sketch

Use a name like @core/my-lib, @config/feature-flags, or @integrations/my-provider. Align scripts and devDependencies with a sibling in the same top-level folder (e.g. core/contracts/package.json, config/constants/package.json, or an existing integrations/ package); adjust main / types / exports to your build output.

JSON
{
  "name": "@core/my-lib",
  "private": true,
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "lint": "eslint --fix . --max-warnings=0",
    "format": "prettier --write --ignore-unknown .",
    "check-types": "tsc --noEmit"
  },
  "devDependencies": {
    "@core/eslint-config": "*",
    "@core/prettier-config": "*",
    "@core/typescript-config": "*",
    "typescript": "^5"
  }
}

Copy tsconfig.json, ESLint/Prettier config, and .lintstagedrc from a nearby package and adapt paths. Add dependencies / peerDependencies as needed (@core/contracts, @config/constants, etc.). Wire the new package into root and consumer package.json files, then run npm install from the repo root.


Back to Advanced topics