Neat Paraskavedekatriaphobia's Meaning

    TypeScript icon, indicating that this package has built-in type declarations

    1.0.7 • Public • Published


    Multithreading can be easy

    » Getting Started

    » Install

    Install with npm:

    npm install subservient

    Install with yarn

    yarn add subservient

    » Basic Example


    import { createFarm } from 'subservient';
    // Create a worker farm
    const farm = createFarm('worker.js', {
        maxSize: 2, // Maximum amount of workers
    (async () => {
        const res = await (await farm.spawn()).hardTask();
        console.log(`Thread returned: ${res}`);
        await farm.end();


    import { expose } from 'subservient';
        hardTask() {
            return new Promise((resolve) => {
                setTimeout(() => resolve('Done!'), 3000);


    Worker returned: Done!

    » Farms

    When a task is called, a Farm looks for an idle worker. If none is found, it creates a new one. After the task is done, it will idle for some time and terminate if no new tasks is received within that time.

    createFarm(file: PathLike, options: FarmOptions): WorkerFarm

    Create a new worker farm.


    • file Path to the worker module
    • options Self-explanatory
      • maxSize Max amount of workers in a farm (default: 3)
      • idleTime Amount of milliseconds that a worker can idle before terminating (default: 5000)

    WorkerFarm.spawn(): Promise<Worker>

    Find an idle worker. If none exists, create one.

    Running a task

    A worker has every method exposed by its corresponding worker module. In the example, expose call in worker.js exposes a function called hardTask. Calling that function on the worker returns a Promise which resolves when the corresponding worker function returns. If the worker function returns a Promise, that promise is awaited before resolving.

    » Pools

    When a pool is created, it will start size amount of parallel threads. Each time a task is sent to the pool, a free thread is chosen and the task is passed to that thread. A pool cannot dynamically create more threads.


    import { createPool } from 'subservient';
    // Create a worker pool with 3 workers
    const pool = createPool('worker.js', 3);
    (async () => {
        const res = await (await pool.spawn()).hardTask();
        console.log(`Thread returned: ${res}`);
        await pool.end();

    worker.js (Same as in the first example):

    import { expose } from 'subservient';
        hardTask() {
            return new Promise((resolve) => {
                setTimeout(() => resolve('Done!'), 3000);

    This does the same thing as in the farm example, but in a slightly different manner.

    The Pool API is the same as the Farm API.

    » Worker Farms vs. Pools

    Subservient provides two different types of worker groups: Farms and Pools. A Pool always has a fixed amount of workers, ready to take tasks. A Farm creates new workers as they are needed and destroys them after a fixed amount of idle time.

    Starting a task in a Farm takes longer because the worker must first be created, but is also more efficient than a pool because there aren't any unused workers lingering around, occupying resources.

    So, use what suits you best. For Example, a server that needs to serve quickly to many users should use a pool because of its smaller delay when starting tasks. On the contrary, a very resource-heavy program should use a farm to save resources when idle.


    npm i subservient

    DownloadsWeekly Downloads






    Unpacked Size

    104 kB

    Total Files


    Last publish


    • avatar