All Versions
Latest Version
Avg Release Cycle
36 days
Latest Release
26 days ago

Changelog History
Page 1

  • v0.14.21 Changes

    April 30, 2022

    20 commits from 2 contributors.

    ๐Ÿ‘ ESM support #1063

    This version contains an ESM-based Moleculer Runner. This Runner is able to load ESM configuration file and ESM services. It can load the CJS services, as well

    Example usage

    moleculer-runner-esm --repl services/**/*.service.mjs

    Moreover, the index.js file is wrapped into index.mjs, so you can import internal modules from the core in ESM modules. E.g.:

    import { ServiceBroker, Errors } from "moleculer";

    Please note, the hot-reload function doesn't work with this ESM Runner. The cause: Node maintainers try to solve the missing features (module cache and module dependency tree) with loaders but this API is not stable yet.

    Other Changes

    • broker.stopping property is created to indicate that broker is in stopping state.

  • v0.14.20 Changes

    April 19, 2022

    52 commits from 8 contributors.

    Dependency logic changed #1077

    In mixed architecture, it's not hard to create a circular service dependency that may cause a dead-lock during the start of Moleculer nodes. The problem is that Moleculer node only sends the local service registry to remote nodes after all local services started properly. As of 0.14.20, this behavior has changed. The new logic uses a debounced registry sending method which is triggered every time a local service, that the node manages, has started().
    โฑ Note that the new method generates more INFO packets, than early versions, during the start of the node. The number of INFO packets depends on the number of the services that the node manages. The debounce timeout, between sending INFO packets, is 1 second.

    Other Changes

    • ๐Ÿ›  fix ActionLogger and TransitLogger middlewares.
    • โšก๏ธ update Datadog Logger using v2 API. #1056
    • โšก๏ธ update dependencies.
    • โšก๏ธ update d.ts file. #1064, #1073
    • ๐Ÿ›  fix pino child logger bindings. #1075

  • v0.14.19 Changes

    January 08, 2022

    69 commits from 7 contributors.

    Custom error recreation feature #1017

    You can create a custom Regenerator class that is able to serialize and deserialize your custom errors. It's necessary when the custom error is created on a remote node and must be serialized to be able to send it back to the caller.

    Create a custom Regenerator

    const { Regenerator, MoleculerError } = require("moleculer").Errors;
    class TimestampedError extends MoleculerError {
        constructor(message, code, type, data, timestamp) {
            super(message, code, type, data);
            this.timestamp = timestamp;
    class CustomRegenerator extends Regenerator {
        restoreCustomError(plainError, payload) {
            const { name, message, code, type, data, timestamp } = plainError;
            switch (name) {
                case "TimestampedError":
                    return new TimestampedError(message, code, type, data, timestamp);
        extractPlainError(err) {
            return {
                timestamp: err.timestamp
    module.exports = CustomRegenerator;

    ๐Ÿ‘‰ Use it in broker options

    // moleculer.config.js
    const CustomRegenerator = require("./custom-regenerator");
    module.exports = {
        errorRegenerator: new CustomRegenerator()

    Error events #1048

    When an error occurred inside ServiceBroker, it's printed to the console, but there was no option that you can process it programmatically (e.g. transfer to an external monitoring service). This feature solves it. Every error inside ServiceBroker broadcasts a local (not transported) event ($transporter.error, $broker.error, $transit.error, $cacher.error, $discoverer.error) what you can listen in your dedicated service or in a middleware.

    Example to listen in an error-tracker service

    module.exports = {
        name: "error-tracker",
        events: {
            "$**.error": {
                handler(ctx) {
                    // Send the error to the tracker

    Example to listen in a middleware or in broker options

    module.exports = {
        created(broker) {
            broker.localBus.on("*.error", payload => {
                // Send the error to the tracker

    Wildcards in Action Hooks #1051

    You can use * wildcard in action names when you use it in Action Hooks.


    hooks: {
        before: {
            // Applies to all actions that start with "create-"
            "create-*": [],
            // Applies to all actions that end with "-user"
            "*-user": [],

    Other Changes

    • โšก๏ธ update dependencies.
    • โšก๏ธ update d.ts file. #1025, #1028, #1032
    • โž• add safetyTags option to tracing exporters. #1052

  • v0.14.18 Changes

    October 20, 2021

    20 commits from 7 contributors.

    ๐Ÿ”„ Changes

    • โšก๏ธ update dependencies.
    • ๐Ÿ”ฆ expose Cacher and Validator middlewares. #1012
    • โšก๏ธ update d.ts file. #1013
    • ๐Ÿ“œ parse user & password from NATS server urls. #1021

  • v0.14.17 Changes

    September 13, 2021

    61 commits from 10 contributors.

    ๐Ÿ”„ Changes

    • reformat codebase with Prettier.
    • ๐Ÿ›  fix binding issue in Pino logger. #974
    • โšก๏ธ update d.ts file. #980 #970
    • transit message handler promises are resolved. #984
    • ๐Ÿ›  fix cacher issue if cacher is not connected. #987
    • ๐Ÿ›  fix Jest open handlers issue. #989
    • ๐Ÿ›  fix cacher cloning issue. #990
    • โž• add custom headers option to Zipkin trace exporter. #993
    • ๐Ÿ›  fix heartbeatTimeout option in BaseDiscoverer. #985
    • โž• add cacher keygen option action definition. #1004
    • โšก๏ธ update dependencies

  • v0.14.16 Changes

    July 21, 2021

    11 commits from 4 contributors.

    ๐Ÿ”„ Changes

    • ๐Ÿ›  fix nats-streaming version in peerDependencies.
    • RedisCacher pingInterval option. #961
    • โšก๏ธ Update NATS transporter messages to debug. #963
    • โšก๏ธ update d.ts file. #964 #966
    • โšก๏ธ update dependencies

  • v0.14.15 Changes

    July 10, 2021

    15 commits from 5 contributors.

    ๐Ÿ”„ Changes

    • ๐Ÿ›  fix nats version in peerDependencies.
    • convert url to servers in [email protected]. #954
    • โž• add typing for mcall settled option. #957
    • โช revert TS ThisType issue in 0.14.14. #958
    • โšก๏ธ update dependencies
    • โž• add useTag259ForMaps: false default option for CBOR serializer to keep the compatibility.

  • v0.14.14 Changes

    June 27, 2021

    105 commits from 11 contributors.

    ๐Ÿ†• New CBOR serializer #905

    CBOR (cbor-x) is a new serializer but faster than any other serializers.


    // moleculer.config.js
    module.exports = {
        logger: true,
        serializer: "CBOR"


    Suite: Serialize packet with 10bytes
    โˆš JSON               509,217 rps
    โˆš Avro               308,711 rps
    โˆš MsgPack             79,932 rps
    โˆš ProtoBuf           435,183 rps
    โˆš Thrift              93,324 rps
    โˆš Notepack           530,121 rps
    โˆš CBOR             1,016,135 rps
       JSON (#)            0%        (509,217 rps)   (avg: 1ฮผs)
       Avro           -39.38%        (308,711 rps)   (avg: 3ฮผs)
       MsgPack         -84.3%         (79,932 rps)   (avg: 12ฮผs)
       ProtoBuf       -14.54%        (435,183 rps)   (avg: 2ฮผs)
       Thrift         -81.67%         (93,324 rps)   (avg: 10ฮผs)
       Notepack        +4.11%        (530,121 rps)   (avg: 1ฮผs)
       CBOR           +99.55%      (1,016,135 rps)   (avg: 984ns)

    settled option in broker.mcall

    The broker.mcall method has a new settled option to receive all Promise results. Without this option, if you make a multi-call and one call is rejected, the response will be a rejected Promise and you don't know how many (and which) calls were rejected.

    If settled: true, the method returns a resolved Promise in any case and the response contains the statuses and responses of all calls.


    const res = await broker.mcall([
        { action: "posts.find", params: { limit: 2, offset: 0 },
        { action: "users.find", params: { limit: 2, sort: "username" } },
        { action: "service.notfound", params: { notfound: 1 } }
    ], { settled: true });

    The res will be something similar to

        { status: "fulfilled", value: [/*... response of `posts.find`...*/] },
        { status: "fulfilled", value: [/*... response of `users.find`...*/] },
        { status: "rejected", reason: {/*... Rejected response/Error`...*/} }

    ๐Ÿ†• New MOLECULER_CONFIG environment variable in Runner

    ๐Ÿ”ง In the Moleculer Runner, you can configure the configuration filename and path with the MOLECULER_CONFIG environment variable. It means, no need to specify the config file with --config argument.

    ๐Ÿ‘Œ Supporting [email protected] in NATS transporter

    ๐Ÿš€ The new nats 2.x.x version has a new breaking API which has locked the NATS transporter for [email protected] library. As of this release, the NATS transporter supports both major versions of the nats library.

    The transporter automatically detects the version of the library and uses the correct API.

    ๐Ÿ“‡ Async custom validator functions and ctx as metadata

    ๐Ÿ“‡ Since [email protected], the FastestValidator supports async custom validators and you can pass metadata for custom validator functions. ๐Ÿ“‡ In Moleculer, the FastestValidator passes the ctx as metadata. It means you can access to the current context, service, broker and you can make async calls (e.g calling another service) in custom checker functions.


    // posts.service.js
    module.exports = {
        name: "posts",
        actions: {
            params: {
                $$async: true,
                owner: { type: "string", custom: async (value, errors, schema, name, parent, context) => {
                    const ctx = context.meta;
                    const res = await"users.isValid", { id: value });
                    if (res !== true)
                        errors.push({ type: "invalidOwner", field: "owner", actual: value });
                    return value;
                } }, 
            /* ... */

    ๐Ÿ”„ Changes

    • ๐Ÿ›  fix node crash in encryption mode with TCP transporter. #849
    • ๐Ÿ”ฆ expose Utils in typescript definition. #909
    • other d.ts improvements. #920, #922, #934, #950
    • ๐Ÿ›  fix etcd3 discoverer lease-loss issue #922
    • catch errors in Compression and Encryption middlewares. #850
    • using optional peer dependencies. #911
    • โž• add relevant packet to to serialization and deserialization calls. #932
    • ๐Ÿ›  fix disabled balancer issue with external discoverer. #933

  • v0.14.13 Changes

    April 09, 2021

    62 commits from 12 contributors.

    ๐Ÿ”„ Changes

    • โšก๏ธ update dependencies
    • ๐ŸŒฒ logging if encryption middleware can't decrypt the data instead of crashing. #853
    • ๐Ÿ›  fix disableHeartbeatChecks option handling. #858
    • ๐Ÿ‘ฎ force scanning only master redis nodes for deletion. #865
    • โž• add more info into waitForServices debug log messages. #870
    • ๐Ÿ›  fix EVENT packet Avro schema. #856
    • ๐Ÿ›  fix array & date conversion in cacher default key generator. #883
    • ๐Ÿ›  fix Datadog tracing exporter. #890
    • ๐Ÿ‘ better elapsed time handling in tracing. #899
    • ๐Ÿ‘Œ improve type definitions. #843, #885, #886
    • โž• add E2E tests for CI (test all built-in transporter & serializers)

  • v0.14.12 Changes

    January 03, 2021

    Other changes

    • โšก๏ธ update dependencies
    • ๐Ÿ‘Œ improved type definitions. #816 #817 #834 #840
    • ๐Ÿ‘Œ support rediss:// cacher URI. #837
    • ๐Ÿ›  fix Event Trace exporter generated events loop. #836
    • ๐Ÿ”„ change log level of node disconnected message. #838
    • ๐Ÿ‘Œ improve the broker.waitForServices response. #843
    • ๐Ÿ›  fix recursive hot-reload issue on Linux OS. #848