a gourmet Next.js starter+boilerplate
Banquet is an all-in-one website starter written in Next.js with TypeScript. It offers a robust template that can be built out to accommodate any frontend needs, with a focus on developer experience and writing scalable, strict code. To that end, it comes preconfigured with linting, formatting, testing, automated code generation, and a robust UI with Chakra and React Icons. As such, Banquet offers a “feast” of tooling and structure to get you started building any kind of modern site you need.
Click to enlarge
Purpose & Goal
The idea for Banquet came from the repetition of using tools like
create-next-app. While each is a powerful, highly usable tool in its own right, I found that whenever creating a new project with them I still ended up having to spend a large amount of time removing unneeded boilerplate and having to configure a suite of dependencies before I could get started. The goal with Banquet was to incorporate a system of boilerplate easier to substitute with custom content, as well as remove the barrier to entry for development by adding crucial tools not usually present in most other templates.
Two of the best custom features included with Banquet are its git hook workflow and its automated code generation.
Banquet uses Plop.js in combination with Handlebars-styled templates for creating new components and pages from the command line, affectionately named the
bake command. It comes preconfigured with templates for a standard TypeScript TSX component, SCSS file, Jest/Testing Library tests, and a generic new Next.js Page. By running
yarn bake from the CLI, the user is presented with a menu of options to choose from. In the most straightforward use case, typing
yarn bake Component NewComponentName creates a directory in
- A template TSX file with default type declarations and imports
- A (optional) accompanying test file that defaults to checking whether the component renders
- A (optional) default index file for exporting all modules from the directory
- A (optional) SCSS module file
This results in the following structure, all from one simple command:
src/ components/ NewComponentName/ NewComponentName.tsx NewComponentName.test.tsx NewComponentName.module.scss index.ts
Click to enlarge
bake command also includes fallbacks in case the user simply enters through the generator menu, as well as functions to randomize names for untitled components to avoid duplicates.
Including a Plop generator was so pleasant to use during the development of Banquet that I now typically use it all the time when developing other projects as well.
Banquet also includes a robust workflow for formatting and caching errors with lint-staged, Husky, Prettier, ESLint, Jest with React Testing Library, and the TypeScript compiler each time you make a commit. First, when staged files are committed, ESLint checks for and fixes any linting errors via the included config file. Then Prettier makes a pass to format all staged files appropriately. Finally, any test files associated with the staged files are run.
If any of these processes fail, the commit fails with warning messages and gives the user a chance to fix any issues before they leave the local repo. As a final check, there is also a
pre-pushhook that does a type-check on all TypeScript code as well. If all these stages pass, the commit is allowed to be pushed remotely, and through the process the stability and strictness of the commit is much more reliable—especially when working with other maintainers or collaborators.
Banquet is actively maintained, though I’m not adding any new features at the moment.
One of the biggest issues I had to deal with in straddling the line between creating a template starter and a boilerplate site was deciding how much structure was “too much”, and how over-customization might be frustrating for some users. Admittedly, Banquet is promoted as an “opinionated” project, but I didn’t want to make it too difficult for users to shape it to their own tastes.
One area where this balance was particularly tricky was in deciding how much of Chakra-UI components to leave bare-bones, and when to create more specific (but with possibly less use cases). There are some custom Layout components that are still simple enough in their configuration to be used in a variety of ways, but I did create a couple more narrowly-focused components based on the standard Chakra modal: a
<ImageModal /> and
These were intended to be the first in a series of similarly customized and expanded components based on Chakra’s UI, and while I’m satisfied with the way the came out, I realized that were I to continue with more and more such components, I would end up closer to creating another UI library rather than a reusable template. I think it can be easy to want to keep scaling, keep widening the depth of support for what you’re creating, but it pays to have a sense of the bigger picture at hand and know when to stop, switch gears, and move on.
All in all, Banquet was a fun project to build that I hope others find useful for their own needs. Much of what I learned and built while working on it has already become more ingrained in my own daily development, and I’m thankful for all I learned during the process.