Tasks

Skier is built around a flexible, modular task pipeline. Each task performs a distinct build step—like generating pages, bundling CSS, or copying static assets. You can use built-in tasks, write your own, and compose them in any order.


What is a Task?

A task is a function or object that describes a build step. Each task receives configuration and context, and can read/write files, update global variables, or generate output.


How Tasks Are Loaded


Task Anatomy

A typical task is created by a factory function (e.g., generatePagesTask(config)) and returns an object like:

{
  name: 'generate-pages',
  config: { ... },
  run: async (config, context) => { ... }
}

Context Object

The context passed to each task includes:


Example: Custom Task

const myCustomTask = {
  name: 'say-hello',
  run: async (config, ctx) => {
    ctx.logger.info('Hello from my custom task!');
    return {};
  }
};

Add it to your pipeline:

module.exports = [
  ...,
  myCustomTask,
  ...
];

Pipeline Order

Tasks run sequentially, top-to-bottom. Output and globals from one task are available to all subsequent tasks.


Sharing Data Between Tasks (Globals)

When a task's run method returns an object (a plain Record<string, any>), Skier merges that object onto the global context. These globals are then available to all subsequent tasks and templates.

Example:

const collectPostsTask = {
  name: 'collect-posts',
  run: async (config, ctx) => {
    // ...collect posts
    return { allPosts };
  }
};

const generateFeedTask = {
  name: 'generate-feed',
  run: async (config, ctx) => {
    // ctx.globals.allPosts is available here!
  }
};

Built-in Tasks

Skier ships with many built-in tasks for common needs. See the Built-ins section for details and examples.


Next: Learn more about Built-in Tasks or Custom Tasks.