Skip to content

Project guidelines

We recommend that your JavaScript project follows the guidelines we’ve outlined below. This will ensure that your project remains modern, healthy, and compatible with other projects within the Cimpress ecosystem.

Your project should be written in TypeScript

Section titled “Your project should be written in TypeScript”

TypeScript enhances JavaScript syntax with types. Adding types to your code makes static analysis possible, which in turn leads to catching more issues and making your business logic more reliable and resilient. We recommend that all projects use TypeScript as their primary language.

Modern React libraries (including Cimpress UI) rely on two important features:

  • hooks, which allow for writing function components, and which are currently in widespread use
  • the new JSX transform, which enables progressive improvements to the inner workings of React, and is the only JSX transform available in React 19+.

React 16.14 is the oldest version of React that supports both of these features. We recommend that you update your React version to at least 16.14 to avoid compatibility issues with modern dependencies.

Your project should not use outdated and/or unmaintained dependencies

Section titled “Your project should not use outdated and/or unmaintained dependencies”

Outdated and/or unmaintained dependencies poison the ecosystem, multiplying security vulnerabilities and preventing modernization. We recommend that you audit your dependencies regularly, prioritizing upgrades and removal of outdated and/or unmaintained dependencies.

A linter analyses your codebase for problems. It can also be configured to enforce code conventions throughout your codebase. We recommend ESLint as our linter of choice.

A formatter keeps your code formatted in a consistent manner, making your codebase more readable and eliminating style discussions from code reviews. We recommend Prettier as our formatter of choice.

The Jest framework that has long been a de facto standard for writing unit tests. Unfortunately, Jest has now become bloated, and it lacks support for modern features like ESM modules. We recommend replacing Jest with a more modern testing framework like Vitest, which has a Jest-compatible API.

Additional guidelines for end-user applications

Section titled “Additional guidelines for end-user applications”

ESM is a modern JavaScript module system. It has been widely supported across browsers since May 2018, and enables important features such as tree-shaking. We recommend that you compile your application to ESM instead of any older module systems like CommonJS, UMD, or AMD.

Your application shouldn’t use create-react-app/react-scripts.

Section titled “Your application shouldn’t use create-react-app/react-scripts.”

For a long time, Create React App has been a go-to tool for easy creation of new React applications. Create React App has now been deprecated, as it was unmaintained for a long time, and it lacks support for modern technologies. For simple applications, we recommend using Vite as a build tool. For more complex applications, we recommend a modern framework like Astro, Next.js, or Remix.

ESM is a modern JavaScript module system. It has been widely supported across browsers since May 2018, and enables important features such as tree-shaking. We recommend that your library outputs ESM instead of any older module systems like CommonJS, UMD, or AMD.

Bear in mind that projects that use older module types cannot use ESM dependencies. If backward compatibility is required, your library can output CommonJS in addition to the ESM output. Take a look at the tshy tool if you need a build tool capable of outputting both ESM and CommonJS formats.

Your library should publish TypeScript declaration files

Section titled “Your library should publish TypeScript declaration files”

When you include TypeScript declaration files in your published library, consumers can benefit from typechecking your library’s API in their own projects. This makes your library easier to use, and gives consumers more confidence in your product. We recommend that the published version of your library includes TypeScript declaration files produced during the build process. If your codebase doesn’t fully use TypeScript yet, you should include manually written TypeScript declaration files in the published version of your library.

Tree-shaking allows bundlers to remove unused code paths when bundling end-user applications. This can make the resulting bundle smaller, resulting in faster loading times and less data usage for end-users. We recommend that you maintain a demo application that uses your library in order to verify tree-shaking support during bundling.

Your library should not bundle its dependencies

Section titled “Your library should not bundle its dependencies”

Bundling your library’s dependencies in its output can cause issues with tree-shaking, and can result in multiple versions of the same dependency being bundled in the end-user application. We recommend that your library’s output remains unbundled to prevent issues for consumers of your library.

Your library should document its API with JSDoc-style comments

Section titled “Your library should document its API with JSDoc-style comments”

JSDoc-style comments are preserved in TypeScript declaration files and are picked up by text editors, providing inline help on how to use your library. We recommend that the public API of your library be decorated with JSDoc-style comments, like in the example below:

foo.ts
/** Logs 'Foo' to the console. */
export function foo(): void {
console.log('Foo');
}

Your library should instruct consumers on how the library should be installed and used

Section titled “Your library should instruct consumers on how the library should be installed and used”

Proper documentation prevents confusion, and makes all of our jobs easier. We recommend that you provide documentation about what your library does, how to install it, and how to use it. This documentation should be kept up-to-date as your library evolves.