Upgrade 0.61 to 0.62

  • Change startupjs and all @startupjs/* dependencies in your package.json to ^0.62
  • Run yarn after the version bump

Upgrade CSSX to v0.3 (Breaking)

CSSX was upgraded to new version 0.3. This changes how eslint is setup and what new features are available when writing pug and styles in pug.

Follow migration guide here to upgrade your eslint config and to understand the new features: https://cssx.dev/migration-guides/0.3

Worker Rewrite (Breaking)

@startupjs/worker was redesigned. This migration guide focuses on moving from the old worker API to the new one.

Quick Migration Checklist

  1. Move your jobs to workerJobs/*.js (if they are not there already).
  2. Keep job handler in export default.
  3. Replace singleton calls at enqueue-time (for example old addSingletonJob(...)) with export const singleton = ... in the job module.
  4. Replace cron payload jobData with data.
  5. Move worker runtime options to startupjs.config.js plugin config (plugins.worker.server).
  6. If you run a dedicated worker microservice in production:
    • set autoStartProduction: false in app server config
    • use npx startupjs start-worker-production for the worker service command

New Job Contract

Each file in workerJobs now uses:

export default async function myJob (data, { log, job }) {
  return { ok: true }
}

export const cron = '*/5 * * * *' // optional
export const worker = 'priority' // optional: 'default' | 'priority'
export const singleton = true // optional: true | false | (data) => key

Singleton Migration

Old

Singleton behavior was configured when adding the job (for example addSingletonJob(...)).

New

Singleton behavior is declared in the job itself:

// global singleton
export const singleton = true

or keyed:

// one in-flight job per key
export const singleton = data => ({ userId: data.userId })

Result: callers now use regular runJob(...), and deduplication is centralized in job definition.

Cron Migration

Old

Cron payload could be defined with jobData.

New

Use only data:

export const cron = {
  pattern: '0 * * * *',
  data: { source: 'hourly' }
}

cron.jobData is deprecated and now rejected.

Running Jobs

Use:

import runJob from '@startupjs/worker'

const result = await runJob('myJob', data)

Behavior:

  • runJob() always waits for completion
  • returns your handler result directly
  • throws if the job fails

data can be any JSON-serializable value (not only objects).

Configuration Migration

Old

Worker runtime behavior was commonly controlled via env/getParam-style configuration.

New

Configure worker in StartupJS plugin options:

export default {
  plugins: {
    worker: {
      server: {
        autoStart: true,
        autoStartProduction: true,
        concurrency: 300,
        jobTimeout: 30000,
        useSeparateProcess: false,
        useWorkerThreads: true
      }
    }
  }
}

Deployment Migration (Important)

App server + embedded worker (default)

No extra setup required. Worker auto-starts by default.

In app server config:

plugins: {
  worker: {
    server: {
      autoStartProduction: false
    }
  }
}

In worker service command:

npx startupjs start-worker-production

If you previously used start-worker in production, switch to start-worker-production.

Optional package.json script (if your deploy uses yarn <script>):

{
  "scripts": {
    "start-worker-production": "npx startupjs start-worker-production"
  }
}

Queue Topology Changes

  • Supported worker names are fixed: default and priority.
  • By default, worker startup runs both queues.
  • By default, jobs go to default.
  • To route a specific job to priority, declare:
export const worker = 'priority'
  • priority means this job can be processed by a dedicated priority capacity, separate from regular background load.

  • This is useful for latency-sensitive jobs (for example OTP, urgent notifications, critical sync).

  • To control which workers are started in a worker process, use:

WORKERS=default,priority
# or
WORKERS=priority

Recommended production topology:

  • Use one dedicated worker microservice running both queues.
  • You do not need to set WORKERS for this default case.

Optional extra reliability topology:

  • Add a second worker microservice running only priority (WORKERS=priority).

This gives stronger guarantees that priority jobs are processed ASAP even when default queue load is high.