---
title: Creating a fleck
description: A fleck is a module but also so much more.
---

If you are following along from the previous getting started
[configuration page](./configuration), you have an application with 3 flecks:

- `@flecks/core`
- `@flecks/server`
- `@flecks/web`

<details>
  <summary>About that "3 flecks" thing...</summary>

  Actually, your server application has 6 flecks at this point:

  - `@flecks/core`
  - `@flecks/core/server`
  - `@flecks/server`
  - `@flecks/server/server`
  - `@flecks/web`
  - `@flecks/web/server`

  flecks will load the `[...]/server` fleck under any fleck that is loaded on the server. This is
  also the case when using `@flecks/web` which will automatically load `[...]/client` flecks
  which are only loaded in the browser. We'll be exploring this specifically in the next section.
  If you're intersted in diving deeper, see [the platforms concept page](#todo).

  Some frameworks make it a little cheesier to work with isomorphic code, but the flecks
  philosophy is that visibility is believability: you'll have to be explicit about which code
  runs where.
</details>

## Your first fleck

Let's make your website greet the user with a good ol' **hello world**.

To do this, you'll be creating your own little fleck. flecks also provides a built-in utility to
create a fleck.

:::note

You may have noticed that your little starter application has a `packages` directory. By default,
flecks structures your application as a monorepo.

This isn't any hard requirement, it's only a suggestion.

:::

### Create the fleck

Let's create our little fleck:

```bash
npx create-fleck say-hello
```

After some output, you'll find your new fleck at `packages/say-hello`. Let's inspect our
`build/flecks.yml`:

```yml title="build/flecks.yml"
'@flecks/core':
  id: 'hello_world'
'@flecks/server': {}
'@flecks/web': {}
// highlight-next-line
'@hello-world/say-hello:./packages/say-hello/src': {}
```

### Aliasing for the win

Notice there's a colon separating the path for this one. This is because this is an
[aliased fleck](#todo). The part before the colon is the alias and the part after is the
path to the package.

By the way, your other application code can import using the alias (e.g.
`require('@hello-world/say-hello');`)
[as if it were a package](https://webpack.js.org/configuration/resolve/#resolvealias).

<details>
  <summary>Wait, my modules don't have to be in <code>node_modules</code>?</summary>

  Nope! When you're developing applications, it can be real nice to
  just pull in local source "packages". If you're wondering how this works, see
  [the alias concept page](#todo).

  That being said, sharing your packages on npm is a cool thing to do, so be rad and share your
  awesome flecks with the rest of us!

  :::warning

  You probably shouldn't do things like name an alias the same thing as a package that actually
  exists in your `node_modules` directory. This is mitigated if you use the default monorepo
  structure (unless your application name is identical to a monorepo organization that already
  exists on `npm`: don't do that).

  If you'd like to help define what happens in these edge cases you could
  always [submit a pull request](https://github.com/cha0s/flecks/compare). :smile:

  :::
</details>

### Your first hook

There is a source file at `packages/say-hello/src/index.js` but for now it's empty. Let's fill it
out a bit:

```javascript title="packages/say-hello/src/index.js"
exports.hooks = {
  '@flecks/web/client.up': async () => {
    window.document.body.append('hello world');
  },
};
```

Now, restart your application and visit your website. Glorious, isn't it?

## Everything so far... plus Electron!

Let's add another core fleck. flecks ships with a core fleck `@flecks/electron`. This runs your
application inside of an instance of [Electron](https://www.electronjs.org/). You'll add the fleck:

```bash
npx flecks add @flecks/electron
```

Then you'll update your `build/flecks.yml` like so:

```yml
'@flecks/core':
  id: 'hello_world'
'@flecks/electron': {}
// highlight-start
'@flecks/server':
  up:
    - '...'
    - '@flecks/web'
    - '@flecks/electron'
// highlight-end
'@flecks/web': {}
'@hello-world/say-hello:./packages/say-hello/src': {}
```

### ~~flecking~~ pecking order

We added some configuration to `@flecks/server`. The `up` key configures the order in which flecks
are initialized when the server comes up. We make sure `@flecks/web` serves a webpage before
`@flecks/electron` tries to visit it.

:::tip

`'...'` just means "everything else": if any other flecks implement that hook then they will run
here. It is valid to provide entries both before and after `'...'`.

The default configuration of
`@flecks/server.up` is simply:

```yml
'@flecks/server':
  up:
    - '...'
```

However in this case the order of hook execution is undefined. That's why we configure it
explicitly.

:::

Finally `npm start` and you will see something like this:

![An image of our simple hello world application running inside an Electron window](./flecks-electron.png)

Isn't it beautiful? :relieved:
