How to provide a root configuration file for a package?

You've probably seen JavaScript packages that require a configuration file in the root of the project, things like webpack.config.js, tailwind.config.js, jest.config.js, the list is endless.

But if you're here, probably you're creating a package and want to offer your users a way to configure your package from the outside. But how do you achieve this, from inside your code that will be sitting inside node_modules?

I didn't know even the words I should be looking for to search, so I started to look at projects that use this type of config and found that Styleguidist uses a package for this...

Turns out that Sindre Sorhus has a package for that too 😅: it's find-up. You pass it a file for it to look up in parent directories.

In my case, I'm creating a React library that depends on a custom property that resides inside a tailwind.config.js in the root of the project. So I can use it in my code like this:

// resolveConfig.js
import findUp from 'find-up'

/**
 * Find a config file
 * @param {string} file - config file name
 * @return path to the file
 */
export default function resolveConfig(file) {
  let configDir
  try {
    configDir = findUp.sync(file)
  } catch (e) {
    return false
  }
  return configDir
}

This will find the file I'm looking for, which is then used to get the content of that file or, if it doesn't exist, the default theme:

// resolveTheme.js
import resolveConfig from './resolveConfig'
import defaultTheme from '../defaultTheme'

const CONFIG_FILE = 'tailwind.config.js'

/**
 * Get the content of a file theme
 */
export default function resolveTheme() {
  const tailwindConfigPath = resolveConfig(CONFIG_FILE)
  let config

  // has tailwind config
  if (tailwindConfigPath) {
    config = require(tailwindConfigPath)
    // has custom theme
    if (config['windmill-react-ui-theme']) {
      return config['windmill-react-ui-theme']
    }
  }

  // fallback to default theme
  return defaultTheme
}

Inside my component I can now use it like this:

import resolveTheme from '../utils/resolveTheme'

// some component
function Button() {
  const theme = resolveTheme()

  // use it somewhere
  classes = theme['button-base']
}

@estevanmaito