banquet

a gourmet Next.js starter+boilerplate

Introduction

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.

Banquet screenshot
Banquet screenshot
Banquet screenshot

Click to enlarge

Purpose & Goal

The idea for Banquet came from the repetition of using tools likecreate-react-app and 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.

Spotlight

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 src/components with:

  • 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
Plop screenshot
Plop screenshot
Plop screenshot

Click to enlarge

The 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.

Status

Banquet is actively maintained, though I’m not adding any new features at the moment.

Lessons Learned

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<Carousal />.

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.

back to home