[{"data":1,"prerenderedAt":1773},["ShallowReactive",2],{"blog-post-\u002Fblog\u002Fkafka-javascript-clients":3},{"id":4,"title":5,"body":6,"date":1758,"description":1759,"extension":1760,"meta":1761,"navigation":1762,"ogImage":1763,"path":1764,"pinned":1765,"seo":1766,"sitemap":1767,"stem":1768,"tags":1769,"__hash__":1772},"blog\u002Fblog\u002Fkafka-javascript-clients.md","Kafka JavaScript Clients: KafkaJS vs. Platformatic Kafka",{"type":7,"value":8,"toc":1723},"minimark",[9,29,32,37,163,172,176,179,182,325,329,343,348,394,399,402,405,417,421,455,460,463,465,477,481,517,522,525,527,534,538,565,570,573,576,579,587,591,599,809,812,815,819,826,1015,1022,1025,1029,1032,1036,1091,1095,1247,1250,1254,1421,1428,1432,1525,1528,1532,1554,1557,1561,1567,1573,1577,1580,1601,1610,1613,1633,1639,1643,1646,1653,1661,1665,1669,1672,1676,1679,1683,1699,1703,1706,1710,1713,1717,1720],[10,11,12,16,17,20,21,24,25,28],"p",{},[13,14,15],"strong",{},"KafkaJS"," has long been a familiar choice for Node.js applications that want a JavaScript API without a native addon. ",[13,18,19],{},"Platformatic Kafka"," offers a newer pure-JavaScript client with stream-based consumers and support focused on current Node.js releases. ",[13,22,23],{},"confluent-kafka-javascript"," provides a Promise-based API influenced by KafkaJS and backed by librdkafka, while ",[13,26,27],{},"node-rdkafka"," remains relevant for applications that use its lower-level native interface.",[10,30,31],{},"This guide compares the four clients' Node.js support, native dependencies, consumer processing models, serialization options, Schema Registry support, and migration costs. A separate set of GitHub metrics shows recent maintenance activity and visible public usage.",[33,34,36],"h2",{"id":35},"quick-decision","Quick decision",[38,39,40,56],"table",{},[41,42,43],"thead",{},[44,45,46,50,53],"tr",{},[47,48,49],"th",{},"Situation",[47,51,52],{},"Best starting point",[47,54,55],{},"What to verify",[57,58,59,76,91,106,121],"tbody",{},[44,60,61,71,73],{},[62,63,64,67,70],"td",{},[13,65,66],{},"Pure JavaScript, stream-first",[68,69],"br",{},"Prioritizes active development and modern Node.js streams",[62,72,19],{},[62,74,75],{},"Supports Node.js 22.22+ or 24.6+; its stream-based consumer model fits; experimental Schema Registry integration is acceptable.",[44,77,78,86,88],{},[62,79,80,83,85],{},[13,81,82],{},"Pure JavaScript, established API",[68,84],{},"Prioritizes a longer public track record and older Node.js support",[62,87,15],{},[62,89,90],{},"Its maintenance model and Kafka feature coverage meet your requirements (latest npm release was Feb 2023).",[44,92,93,101,103],{},[62,94,95,98,100],{},[13,96,97],{},"librdkafka with a Promise API",[68,99],{},"Needs Confluent support or a KafkaJS-influenced API",[62,102,23],{},[62,104,105],{},"Prebuilt binaries support every target operating system, CPU architecture, Node.js version, and packaging environment.",[44,107,108,116,118],{},[62,109,110,113,115],{},[13,111,112],{},"Direct librdkafka integration",[68,114],{},"Needs event-driven, callback, or Node.js stream APIs",[62,117,27],{},[62,119,120],{},"Its lower-level configuration and API provide enough value to prefer it over Confluent's newer Promise client.",[44,122,123,131,137],{},[62,124,125,128,130],{},[13,126,127],{},"Migrating from KafkaJS",[68,129],{},"Seeking active maintenance or features unavailable in KafkaJS",[62,132,133,134,136],{},"confluent-kafka-javascript (closest API)",[68,135],{},"or Platformatic Kafka (pure JavaScript)",[62,138,139,140,144,145,148,149,156,157,162],{},"Confluent retains ",[141,142,143],"code",{},"eachMessage","\u002F",[141,146,147],{},"eachBatch","; Platformatic moves consumer processing to streams. See the ",[150,151,155],"a",{"href":152,"rel":153},"https:\u002F\u002Fgithub.com\u002Fconfluentinc\u002Fconfluent-kafka-javascript\u002Fblob\u002Fmaster\u002FMIGRATION.md",[154],"nofollow","Confluent migration guide"," and ",[150,158,161],{"href":159,"rel":160},"https:\u002F\u002Fgithub.com\u002Fplatformatic\u002Fkafka\u002Fblob\u002Fmain\u002Fmigration\u002FREADME.md",[154],"Platformatic migration guide",".",[164,165,166],"blockquote",{},[10,167,168,171],{},[13,169,170],{},"Tip:"," These clients provide Kafka messaging, not stateful stream processing. For windows, joins, or managed state stores, use a dedicated framework such as Apache Flink or Kafka Streams.",[33,173,175],{"id":174},"kafka-javascript-clients-compared","Kafka JavaScript clients compared",[10,177,178],{},"Versions and capabilities checked against official documentation and npm metadata on 28 Aug 2026.",[10,180,181],{},"All four clients also support TLS and mutual TLS.",[38,183,184,203],{},[41,185,186],{},[44,187,188,191,194,197,200],{},[47,189,190],{},"Capability",[47,192,193],{},"Platformatic Kafka (2.11.0)",[47,195,196],{},"KafkaJS (2.2.4)",[47,198,199],{},"confluent-kafka-javascript (1.10.0)",[47,201,202],{},"node-rdkafka (3.6.1)",[57,204,205,223,242,272,289,306],{},[44,206,207,212,215,218,221],{},[62,208,209],{},[13,210,211],{},"Runtime",[62,213,214],{},"Pure TypeScript\u002FJavaScript; no native addon",[62,216,217],{},"Pure JavaScript; no native addon",[62,219,220],{},"librdkafka native addon",[62,222,220],{},[44,224,225,230,233,236,239],{},[62,226,227],{},[13,228,229],{},"Node.js",[62,231,232],{},"22.22+ or 24.6+",[62,234,235],{},"14+",[62,237,238],{},"18+",[62,240,241],{},"16+",[44,243,244,249,255,262,269],{},[62,245,246],{},[13,247,248],{},"Consumer",[62,250,251,254],{},[141,252,253],{},"Readable"," streams",[62,256,257,259,260],{},[141,258,143],{}," \u002F ",[141,261,147],{},[62,263,264,259,266,268],{},[141,265,143],{},[141,267,147],{},"; callback API",[62,270,271],{},"Events, callbacks, streams",[44,273,274,279,282,284,287],{},[62,275,276],{},[13,277,278],{},"Authentication",[62,280,281],{},"PLAIN, SCRAM, OAUTHBEARER",[62,283,281],{},[62,285,286],{},"PLAIN, SCRAM, OAUTHBEARER, GSSAPI",[62,288,286],{},[44,290,291,296,299,302,304],{},[62,292,293],{},[13,294,295],{},"Transactions",[62,297,298],{},"Idempotence and transactions",[62,300,301],{},"Transactions; idempotence experimental",[62,303,298],{},[62,305,298],{},[44,307,308,313,316,319,322],{},[62,309,310],{},[13,311,312],{},"Schema Registry",[62,314,315],{},"Built in (experimental)",[62,317,318],{},"Separate KafkaJS package",[62,320,321],{},"First-party package",[62,323,324],{},"No built-in integration",[326,327,19],"h3",{"id":328},"platformatic-kafka",[10,330,331,335,336,338,339,342],{},[150,332,19],{"href":333,"rel":334},"https:\u002F\u002Fgithub.com\u002Fplatformatic\u002Fkafka",[154]," is a pure TypeScript\u002FJavaScript client for current Node.js releases. Its consumer returns a ",[141,337,253],{}," stream, making ",[141,340,341],{},"for await...of",", stream composition, and Node.js backpressure part of the consumer design.",[10,344,345],{},[13,346,347],{},"Capabilities and limitations",[349,350,351,372,378],"ul",{},[352,353,354,357,358,363,364,367,368,371],"li",{},[13,355,356],{},"Kafka and tooling:"," Version 2.11.0 supports Kafka 3.5 through 4.2, including the KIP-848 consumer group protocol, with implemented features listed in a ",[150,359,362],{"href":360,"rel":361},"https:\u002F\u002Fgithub.com\u002Fplatformatic\u002Fkafka\u002Fblob\u002Fmain\u002Fdocs\u002Fkips.md",[154],"KIP support matrix",". It includes serializers, ",[141,365,366],{},"bigint"," offsets and timestamps, and ",[141,369,370],{},"node:diagnostics_channel"," integration.",[352,373,374,377],{},[13,375,376],{},"Schema Registry:"," Built-in Avro, Protobuf, and JSON Schema support is experimental and can change outside a major release.",[352,379,380,383,384,387,388,393],{},[13,381,382],{},"Deployment constraints:"," It requires Node.js 22.22+ or 24.6+ and supports PLAIN, SCRAM, and OAUTHBEARER, but not GSSAPI\u002FKerberos. Consumer streams default to a ",[141,385,386],{},"highWaterMark"," of 1024 messages, which should be reduced for large records. The project also publishes ",[150,389,392],{"href":390,"rel":391},"https:\u002F\u002Fgithub.com\u002Fplatformatic\u002Fkafka\u002Fblob\u002Fmain\u002FBENCHMARKS.md",[154],"benchmarks"," that you can use as a reference for your own testing.",[10,395,396],{},[13,397,398],{},"When to choose Platformatic Kafka",[10,400,401],{},"Choose Platformatic Kafka for a new service that can run on a current Node.js release and needs KIP-848 without a native addon or benefits from stream-based consumption. Choose another client if the deployment requires GSSAPI\u002FKerberos or stable Schema Registry APIs.",[326,403,15],{"id":404},"kafkajs",[10,406,407,411,412,156,414,416],{},[150,408,15],{"href":409,"rel":410},"https:\u002F\u002Fgithub.com\u002Ftulios\u002Fkafkajs",[154]," is a pure JavaScript client with a Promise-based API and ",[141,413,143],{},[141,415,147],{}," consumer handlers. It supports older Node.js releases without a native addon.",[10,418,419],{},[13,420,347],{},[349,422,423,429,441],{},[352,424,425,428],{},[13,426,427],{},"Protocol and authentication:"," KafkaJS supports producers, transactions, headers, and an Admin client, plus PLAIN, SCRAM, and OAUTHBEARER authentication, but not GSSAPI\u002FKerberos. Amazon MSK IAM works through AWS's signer package and an OAUTHBEARER token provider. KafkaJS uses classic consumer groups with a built-in round-robin assigner; custom assigners are possible, but KIP-848 and a built-in cooperative-sticky assigner are absent.",[352,430,431,434,435,440],{},[13,432,433],{},"Compression and schemas:"," GZIP ",[150,436,439],{"href":437,"rel":438},"https:\u002F\u002Fkafka.js.org\u002Fdocs\u002Fproducing#compression",[154],"compression"," is included; Snappy, LZ4, and ZSTD require additional codec packages, and Schema Registry support comes from a separate KafkaJS package. KafkaJS decompresses records but does not expose the original compression codec on consumed messages.",[352,442,443,446,447,454],{},[13,444,445],{},"Release status and Node.js 24:"," The latest release is version 2.2.4, published in February 2023. On Node.js 24, it can schedule a 1 ms timer loop on idle connections, causing a ",[150,448,451],{"href":449,"rel":450},"https:\u002F\u002Fgithub.com\u002Ftulios\u002Fkafkajs\u002Fissues\u002F1751",[154],[141,452,453],{},"TimeoutNegativeWarning"," and unnecessary CPU use.",[10,456,457],{},[13,458,459],{},"When to choose KafkaJS",[10,461,462],{},"Keep KafkaJS when an existing application is stable and does not need GSSAPI\u002FKerberos, a built-in cooperative-sticky assigner, or KIP-848. For a new pure JavaScript service, prefer Platformatic Kafka if its runtime and stream model fit; choose Confluent's client when librdkafka features, first-party Schema Registry support, or commercial support matters.",[326,464,23],{"id":23},[10,466,467,471,472,156,474,476],{},[150,468,23],{"href":469,"rel":470},"https:\u002F\u002Fgithub.com\u002Fconfluentinc\u002Fconfluent-kafka-javascript",[154]," combines librdkafka with a KafkaJS-influenced Promise API. It retains ",[141,473,143],{},[141,475,147],{}," and also provides a callback API derived from node-rdkafka.",[10,478,479],{},[13,480,347],{},[349,482,483,489,507],{},[352,484,485,488],{},[13,486,487],{},"Kafka features:"," Version 1.10.0 includes librdkafka 2.15.0, so Kafka 4 deployments can use KIP-848. GZIP, Snappy, LZ4, and ZSTD require no additional JavaScript codec packages, and authentication supports GSSAPI\u002FKerberos in addition to PLAIN, SCRAM, and OAUTHBEARER.",[352,490,491,494,495,498,499,506],{},[13,492,493],{},"Packaging and schemas:"," Confluent publishes prebuilt binaries for supported Linux, macOS, and Windows combinations, while Yarn and pnpm support remain experimental. Unsupported targets may require ",[141,496,497],{},"node-gyp"," and a C\u002FC++ toolchain. Schema Registry support comes from the first-party ",[150,500,503],{"href":501,"rel":502},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@confluentinc\u002Fschemaregistry",[154],[141,504,505],{},"@confluentinc\u002Fschemaregistry"," package.",[352,508,509,512,513,516],{},[13,510,511],{},"KafkaJS compatibility:"," The compatible layer reduces migration work but does not support custom producer partitioners, custom consumer assigners, or ",[141,514,515],{},"consumer.stop()",", and its Admin API covers only a subset of KafkaJS methods.",[10,518,519],{},[13,520,521],{},"When to choose confluent-kafka-javascript",[10,523,524],{},"Choose Confluent's client when a new service needs GSSAPI\u002FKerberos, first-party Schema Registry support, commercial support, or the closest maintained migration path from KafkaJS. Verify binary availability for every development and production target.",[326,526,27],{"id":27},[10,528,529,533],{},[150,530,27],{"href":531,"rel":532},"https:\u002F\u002Fgithub.com\u002FBlizzard\u002Fnode-rdkafka",[154]," exposes librdkafka configuration through event-driven producers and consumers, callbacks, stream helpers, delivery reports, and transactions.",[10,535,536],{},[13,537,347],{},[349,539,540,545,559],{},[352,541,542,544],{},[13,543,487],{}," Version 3.6.1 includes librdkafka 2.12.0, which supports KIP-848 with Kafka 4 brokers. Authentication follows librdkafka and includes GSSAPI\u002FKerberos, while the direct configuration surface suits applications that depend on native callbacks and settings.",[352,546,547,550,551,554,555,558],{},[13,548,549],{},"Producer and Admin APIs:"," The standard Producer API must call ",[141,552,553],{},"poll()"," or configure ",[141,556,557],{},"setPollInterval()","; otherwise, delivery reports are not emitted and the internal queue can eventually fill. The Admin client creates and deletes topics and increases partition counts but does not expose librdkafka's configuration-alteration APIs.",[352,560,561,564],{},[13,562,563],{},"Deployment:"," The native addon must be tested on every target. Linux and macOS are the main supported platforms, while Windows support may lag. Confluent's newer client shares this lineage but provides a documented prebuilt-binary support matrix and a Promise-oriented API.",[10,566,567],{},[13,568,569],{},"When to choose node-rdkafka",[10,571,572],{},"Keep node-rdkafka when an existing application relies on its API or direct librdkafka configuration. For a new service, choose Confluent's client unless the lower-level event or stream interface is a specific requirement.",[33,574,127],{"id":575},"migrating-from-kafkajs",[10,577,578],{},"This guide covers two practical migration paths for KafkaJS applications. confluent-kafka-javascript retains much of the KafkaJS API and usually requires fewer application changes, but it introduces a native addon. Platformatic Kafka has no native addon, but consumer processing must be rewritten around Node.js streams.",[164,580,581],{},[10,582,583,586],{},[13,584,585],{},"Amazon MSK IAM:"," KafkaJS uses an external AWS signer through OAUTHBEARER. Before migrating, verify the target client's token-provider and token-refresh integration.",[326,588,590],{"id":589},"migrating-from-kafkajs-to-platformatic-kafka","Migrating from KafkaJS to Platformatic Kafka",[10,592,593,594,598],{},"Platformatic provides a detailed ",[150,595,597],{"href":159,"rel":596},[154],"KafkaJS migration guide",". The migration changes both APIs and application behavior.",[38,600,601,615],{},[41,602,603],{},[44,604,605,608,610,612],{},[47,606,607],{},"Area",[47,609,15],{},[47,611,19],{},[47,613,614],{},"Migration impact",[57,616,617,656,681,710,741,766,791],{},[44,618,619,624,631,645],{},[62,620,621],{},[13,622,623],{},"Client & config",[62,625,626,627,630],{},"Shared ",[141,628,629],{},"new Kafka()"," factory",[62,632,633,634,637,638,640,641,644],{},"Direct ",[141,635,636],{},"Producer",", ",[141,639,248],{},", and ",[141,642,643],{},"Admin"," clients",[62,646,647,648,651,652,655],{},"Separate configs; rename ",[141,649,650],{},"brokers"," to ",[141,653,654],{},"bootstrapBrokers","; flatten retries; uppercase SASL values.",[44,657,658,663,672,678],{},[62,659,660],{},[13,661,662],{},"Connections",[62,664,665,666,259,669],{},"Explicit ",[141,667,668],{},"connect()",[141,670,671],{},"disconnect()",[62,673,674,675],{},"Lazy connect; explicit ",[141,676,677],{},"close()",[62,679,680],{},"Remove startup connects; close clients during shutdown.",[44,682,683,688,698,703],{},[62,684,685],{},[13,686,687],{},"Producing",[62,689,690,691,694,695],{},"Topic on ",[141,692,693],{},"send()","; separate ",[141,696,697],{},"sendBatch()",[62,699,700,701],{},"Topic per message; one ",[141,702,693],{},[62,704,705,706,709],{},"Move ",[141,707,708],{},"topic"," into messages; pass compression as a string.",[44,711,712,717,730,738],{},[62,713,714],{},[13,715,716],{},"Consumption & commits",[62,718,719,722,723,726,727],{},[141,720,721],{},"subscribe()"," + ",[141,724,725],{},"run()","; ",[141,728,729],{},"commitOffsets()",[62,731,732,734,735],{},[141,733,253],{}," stream; stream modes; ",[141,736,737],{},"message.commit()",[62,739,740],{},"Rewrite loops, start positions, manual commits, and shutdown.",[44,742,743,748,751,763],{},[62,744,745],{},[13,746,747],{},"Data & serialization",[62,749,750],{},"String offsets\u002Ftimestamps; object headers",[62,752,753,637,755,758,759,762],{},[141,754,366],{},[141,756,757],{},"Map","; optional serializers; raw ",[141,760,761],{},"Buffer"," by default",[62,764,765],{},"Update types and JSON handling; preserve the existing wire format.",[44,767,768,772,777,782],{},[62,769,770],{},[13,771,295],{},[62,773,774],{},[141,775,776],{},"producer.transaction()",[62,778,779],{},[141,780,781],{},"producer.beginTransaction()",[62,783,784,785,156,788,162],{},"Set ",[141,786,787],{},"idempotent: true",[141,789,790],{},"transactionalId",[44,792,793,798,801,806],{},[62,794,795],{},[13,796,797],{},"Operational APIs",[62,799,800],{},"KafkaJS events, errors, and Admin methods",[62,802,803,805],{},[141,804,370],{},"; different error and Admin APIs",[62,807,808],{},"Migrate monitoring, error handling, and Admin calls.",[10,810,811],{},"The consumer rewrite is the main migration risk. Test partition ordering, commit timing, rebalances, and graceful shutdown with in-flight records.",[10,813,814],{},"Producer migration also needs wire-level verification. A serialization change can alter message keys, JSON encoding, headers, or Schema Registry framing even when the TypeScript values look equivalent.",[326,816,818],{"id":817},"migrating-from-kafkajs-to-confluent-kafka-javascript","Migrating from KafkaJS to confluent-kafka-javascript",[10,820,821,822,825],{},"Confluent provides an official ",[150,823,597],{"href":152,"rel":824},[154]," for its compatibility layer. The main processing APIs remain familiar, but configuration placement and some runtime behavior differ.",[38,827,828,840],{},[41,829,830],{},[44,831,832,834,836,838],{},[47,833,607],{},[47,835,15],{},[47,837,23],{},[47,839,614],{},[57,841,842,864,891,919,939,963,983,998],{},[44,843,844,849,852,861],{},[62,845,846],{},[13,847,848],{},"Imports & config",[62,850,851],{},"KafkaJS configuration shapes",[62,853,854,856,857,860],{},[141,855,15],{}," namespace; nested ",[141,858,859],{},"kafkaJS"," blocks",[62,862,863],{},"Move compatible options; map TLS and librdkafka settings separately.",[44,865,866,871,882,885],{},[62,867,868],{},[13,869,870],{},"Producer options",[62,872,873,874,637,877,640,879],{},"Per-send ",[141,875,876],{},"acks",[141,878,439],{},[141,880,881],{},"timeout",[62,883,884],{},"Set during producer creation",[62,886,887,888,162],{},"Move all three options; review batching and ",[141,889,890],{},"flush()",[44,892,893,898,909,912],{},[62,894,895],{},[13,896,897],{},"Consumer options",[62,899,900,903,904,906,907],{},[141,901,902],{},"fromBeginning"," on ",[141,905,721],{},"; auto-commit on ",[141,908,725],{},[62,910,911],{},"Set during consumer creation; 5-second auto-commit interval by default",[62,913,914,915,918],{},"Move options; ",[141,916,917],{},"autoCommitThreshold"," is unsupported.",[44,920,921,926,933,936],{},[62,922,923],{},[13,924,925],{},"Consumer handlers",[62,927,928,259,930,932],{},[141,929,143],{},[141,931,147],{},"; callable heartbeat",[62,934,935],{},"Same handler names; client-built batches; automatic heartbeats",[62,937,938],{},"Test batch resolution, concurrency, rebalances, and commits.",[44,940,941,946,951,954],{},[62,942,943],{},[13,944,945],{},"Unsupported APIs",[62,947,948,949],{},"Custom networking, partitioners, assigners, and ",[141,950,515],{},[62,952,953],{},"Unsupported in the compatibility layer",[62,955,956,957,960,961,162],{},"Replace broker functions and ",[141,958,959],{},"socketFactory","; use ",[141,962,671],{},[44,964,965,970,973,980],{},[62,966,967],{},[13,968,969],{},"Errors & Admin",[62,971,972],{},"KafkaJS errors, retries, and Admin methods",[62,974,975,976,979],{},"Prefer ",[141,977,978],{},"error.code","; different retries; subset Admin API",[62,981,982],{},"Update error branches, retry assumptions, and Admin calls.",[44,984,985,990,993,995],{},[62,986,987],{},[13,988,989],{},"Native packaging",[62,991,992],{},"Pure JavaScript",[62,994,220],{},[62,996,997],{},"Verify binaries in CI, containers, and production.",[44,999,1000,1004,1009,1012],{},[62,1001,1002],{},[13,1003,312],{},[62,1005,1006],{},[141,1007,1008],{},"@kafkajs\u002Fconfluent-schema-registry",[62,1010,1011],{},"Keep it or adopt Confluent's package",[62,1013,1014],{},"Treat a package change as a separate migration.",[10,1016,1017,1018,1021],{},"Applications using transactions need an additional check: a transactional producer cannot send outside an active transaction, and ",[141,1019,1020],{},"sendOffsets()"," receives the consumer instead of a consumer group ID.",[10,1023,1024],{},"Code churn is lower than with Platformatic, but verify rebalance, commit, retry, and error semantics and native binaries on every target.",[33,1026,1028],{"id":1027},"repository-signals","Repository signals",[10,1030,1031],{},"The tables below compare the four clients' GitHub activity, maintenance, and public usage using the same metrics and assessment rules. Snapshot: 28 Aug 2026.",[326,1033,1035],{"id":1034},"project-overview","Project overview",[38,1037,1038,1053],{},[41,1039,1040],{},[44,1041,1042,1045,1047,1049,1051],{},[47,1043,1044],{},"Attribute",[47,1046,19],{},[47,1048,15],{},[47,1050,23],{},[47,1052,27],{},[57,1054,1055,1074],{},[44,1056,1057,1062,1065,1068,1071],{},[62,1058,1059],{},[13,1060,1061],{},"Repository created",[62,1063,1064],{},"28 Feb 2025",[62,1066,1067],{},"1 Aug 2017",[62,1069,1070],{},"7 Nov 2023",[62,1072,1073],{},"11 Aug 2016",[44,1075,1076,1081,1084,1087,1089],{},[62,1077,1078],{},[13,1079,1080],{},"License",[62,1082,1083],{},"Apache-2.0",[62,1085,1086],{},"MIT",[62,1088,1086],{},[62,1090,1086],{},[326,1092,1094],{"id":1093},"activity","Activity",[38,1096,1097,1112],{},[41,1098,1099],{},[44,1100,1101,1104,1106,1108,1110],{},[47,1102,1103],{},"Metric",[47,1105,19],{},[47,1107,15],{},[47,1109,23],{},[47,1111,27],{},[57,1113,1114,1133,1152,1171,1190,1209,1228],{},[44,1115,1116,1121,1124,1127,1130],{},[62,1117,1118],{},[13,1119,1120],{},"Latest default-branch commit",[62,1122,1123],{},"26 Aug 2026",[62,1125,1126],{},"16 May 2024",[62,1128,1129],{},"27 Aug 2026",[62,1131,1132],{},"3 Dec 2025",[44,1134,1135,1140,1143,1146,1149],{},[62,1136,1137],{},[13,1138,1139],{},"Latest GitHub Release",[62,1141,1142],{},"v2.11.0 (25 Aug 2026)",[62,1144,1145],{},"v2.2.4 (27 Feb 2023)",[62,1147,1148],{},"v1.10.1-alpha.0 (26 Aug 2026)",[62,1150,1151],{},"v3.6.1 (3 Dec 2025)",[44,1153,1154,1159,1162,1165,1168],{},[62,1155,1156],{},[13,1157,1158],{},"GitHub Releases (12 mo)",[62,1160,1161],{},"54",[62,1163,1164],{},"0",[62,1166,1167],{},"21",[62,1169,1170],{},"2",[44,1172,1173,1178,1181,1184,1187],{},[62,1174,1175],{},[13,1176,1177],{},"Commits",[62,1179,1180],{},"69 (90 d) · 218 (12 mo)",[62,1182,1183],{},"0 (90 d) · 0 (12 mo)",[62,1185,1186],{},"12 (90 d) · 83 (12 mo)",[62,1188,1189],{},"0 (90 d) · 2 (12 mo)",[44,1191,1192,1197,1200,1203,1206],{},[62,1193,1194],{},[13,1195,1196],{},"Issue flow (90 d)",[62,1198,1199],{},"27 opened · 33 closed",[62,1201,1202],{},"8 opened · 1 closed",[62,1204,1205],{},"7 opened · 3 closed",[62,1207,1208],{},"3 opened · 0 closed",[44,1210,1211,1216,1219,1222,1225],{},[62,1212,1213],{},[13,1214,1215],{},"PR flow (90 d)",[62,1217,1218],{},"50 opened · 55 merged",[62,1220,1221],{},"10 opened · 0 merged",[62,1223,1224],{},"26 opened · 12 merged",[62,1226,1227],{},"2 opened · 0 merged",[44,1229,1230,1235,1238,1241,1244],{},[62,1231,1232],{},[13,1233,1234],{},"Activity assessment",[62,1236,1237],{},"🟢 69 commits and 55 merged PRs in the last 90 days.",[62,1239,1240],{},"🔴 No commit on the default branch in 834 days.",[62,1242,1243],{},"🟢 12 commits and 12 merged PRs in the last 90 days.",[62,1245,1246],{},"🔴 No commits and no merged PRs in the last 90 days.",[10,1248,1249],{},"Release figures cover GitHub Releases, not npm. Confluent's latest GitHub entry is a prerelease; the capability table uses the stable 1.10.0 release.",[326,1251,1253],{"id":1252},"maintenance","Maintenance",[38,1255,1256,1270],{},[41,1257,1258],{},[44,1259,1260,1262,1264,1266,1268],{},[47,1261,1103],{},[47,1263,19],{},[47,1265,15],{},[47,1267,23],{},[47,1269,27],{},[57,1271,1272,1290,1309,1328,1346,1365,1383,1402],{},[44,1273,1274,1279,1282,1284,1287],{},[62,1275,1276],{},[13,1277,1278],{},"Active commit authors (12 mo)",[62,1280,1281],{},"29",[62,1283,1164],{},[62,1285,1286],{},"14",[62,1288,1289],{},"1",[44,1291,1292,1297,1300,1303,1306],{},[62,1293,1294],{},[13,1295,1296],{},"PR merge distribution (12 mo)",[62,1298,1299],{},"2 people · largest share: 76%",[62,1301,1302],{},"0 people · no recorded non-bot merges",[62,1304,1305],{},"13 people · largest share: 36%",[62,1307,1308],{},"1 person · largest share: 100%",[44,1310,1311,1316,1319,1322,1325],{},[62,1312,1313],{},[13,1314,1315],{},"Issue backlog",[62,1317,1318],{},"0 open issues",[62,1320,1321],{},"355 open · median age 3.8 y",[62,1323,1324],{},"76 open · median age 1.4 y",[62,1326,1327],{},"107 open · median age 3.3 y",[44,1329,1330,1335,1338,1341,1344],{},[62,1331,1332],{},[13,1333,1334],{},"Issue closure rate",[62,1336,1337],{},"21\u002F22 closed within 30 d · 21\u002F22 within 90 d",[62,1339,1340],{},"N\u002FA — no issues in measurement window",[62,1342,1343],{},"4\u002F10 closed within 30 d · 5\u002F10 within 90 d",[62,1345,1340],{},[44,1347,1348,1353,1356,1359,1362],{},[62,1349,1350],{},[13,1351,1352],{},"PR backlog",[62,1354,1355],{},"2 open · median age 67 d",[62,1357,1358],{},"62 open · median age 2.3 y",[62,1360,1361],{},"34 open · median age 192 d",[62,1363,1364],{},"22 open · median age 1.7 y",[44,1366,1367,1372,1375,1378,1381],{},[62,1368,1369],{},[13,1370,1371],{},"Median PR merge time (90 d)",[62,1373,1374],{},"1.2 d (n=55)",[62,1376,1377],{},"N\u002FA — no merged PRs in window",[62,1379,1380],{},"23.3 h (n=12)",[62,1382,1377],{},[44,1384,1385,1390,1393,1396,1399],{},[62,1386,1387],{},[13,1388,1389],{},"Responsiveness assessment",[62,1391,1392],{},"🟡 Median open PR age is 67 d.",[62,1394,1395],{},"🔴 No PRs merged in 90 d, while 62 open PRs have a median age of 2.3 y.",[62,1397,1398],{},"🟡 New PRs merge in a median of 23.3 h (n=12), but 34 open PRs have a median age of 192 d.",[62,1400,1401],{},"🔴 No PRs merged in 90 d, while 22 open PRs have a median age of 1.7 y.",[44,1403,1404,1409,1412,1415,1418],{},[62,1405,1406],{},[13,1407,1408],{},"PR merge concentration assessment",[62,1410,1411],{},"🟡 2 people merged PRs in 12 mo; the most active account handled 76% of merges.",[62,1413,1414],{},"N\u002FA — no recorded non-bot PR mergers in 12 mo",[62,1416,1417],{},"🟢 13 people merged PRs in 12 mo; the most active account handled 36% of merges.",[62,1419,1420],{},"🔴 1 person merged PRs in 12 mo and handled 100% of merges.",[10,1422,1423,1424,1427],{},"PR merge distribution counts non-bot ",[141,1425,1426],{},"mergedBy"," accounts, so automated merges may undercount human reviewers. Issue closure rates use issues opened 90–180 days before the snapshot, giving each issue a full 90-day window.",[326,1429,1431],{"id":1430},"public-usage-and-interest","Public usage and interest",[38,1433,1434,1448],{},[41,1435,1436],{},[44,1437,1438,1440,1442,1444,1446],{},[47,1439,1103],{},[47,1441,19],{},[47,1443,15],{},[47,1445,23],{},[47,1447,27],{},[57,1449,1450,1469,1488,1507],{},[44,1451,1452,1457,1460,1463,1466],{},[62,1453,1454],{},[13,1455,1456],{},"Stars",[62,1458,1459],{},"410",[62,1461,1462],{},"4,004",[62,1464,1465],{},"303",[62,1467,1468],{},"2,211",[44,1470,1471,1476,1479,1482,1485],{},[62,1472,1473],{},[13,1474,1475],{},"Forks",[62,1477,1478],{},"49",[62,1480,1481],{},"600",[62,1483,1484],{},"43",[62,1486,1487],{},"403",[44,1489,1490,1495,1498,1501,1504],{},[62,1491,1492],{},[13,1493,1494],{},"GitHub dependents (Used by)",[62,1496,1497],{},"40",[62,1499,1500],{},"32,281",[62,1502,1503],{},"11",[62,1505,1506],{},"2,561",[44,1508,1509,1514,1517,1520,1522],{},[62,1510,1511],{},[13,1512,1513],{},"Public usage assessment",[62,1515,1516],{},"🔴 Limited visible usage",[62,1518,1519],{},"🟢 Broadest visible usage",[62,1521,1516],{},[62,1523,1524],{},"🟡 Established visible usage",[10,1526,1527],{},"GitHub dependents are approximate public-repository counts.",[326,1529,1531],{"id":1530},"overall-repository-signals","Overall repository signals",[349,1533,1534,1539,1544,1549],{},[352,1535,1536,1538],{},[13,1537,19],{}," has the strongest recent activity, but it is the youngest project, has limited visible adoption, and recorded PR merging is concentrated among two people.",[352,1540,1541,1543],{},[13,1542,15],{}," has by far the broadest visible adoption, but its default branch and releases are inactive and its issue and PR backlogs are old.",[352,1545,1546,1548],{},[13,1547,23],{}," is active and PR merging is distributed across more contributors, but visible adoption remains limited and its PR backlog is aging.",[352,1550,1551,1553],{},[13,1552,27],{}," has established visible adoption, but it has no recent commits or merged PRs and recorded PR merging is concentrated in one person.",[10,1555,1556],{},"These are maintenance and adoption signals, not evidence of runtime quality or performance.",[33,1558,1560],{"id":1559},"test-javascript-kafka-clients-with-kafma","Test JavaScript Kafka clients with Kafma",[10,1562,1563,1564,1566],{},"A resolved ",[141,1565,693],{}," does not prove that the stored bytes, headers, or schema framing match downstream expectations.",[10,1568,1569,1572],{},[150,1570,1571],{"href":144},"Kafma"," lets you inspect Kafka records and send controlled test traffic from one desktop workspace, without writing temporary debugging scripts.",[326,1574,1576],{"id":1575},"inspect-records-and-test-consumers-in-console","Inspect records and test consumers in Console",[10,1578,1579],{},"Run your application producer against a test topic, then inspect the record in Kafma:",[349,1581,1582,1595],{},[352,1583,1584,1587,1588,156,1591,1594],{},[13,1585,1586],{},"Check encoding:"," With Schema Registry configured, Kafma automatically decodes Avro, Protobuf, and JSON Schema records. Switch between ",[13,1589,1590],{},"Decoded",[13,1592,1593],{},"Raw"," to verify the decoded value, schema ID, and original bytes.",[352,1596,1597,1600],{},[13,1598,1599],{},"Check metadata:"," Verify the stored key, headers, partition, offset, and timestamp, especially after changing serializers or header mappings.",[10,1602,1603],{},[1604,1605],"img",{"alt":1606,"height":1607,"src":1608,"width":1609},"Kafma inspecting an automatically decoded Avro record with schema ID 7, metadata, and the Raw view available",1520,"https:\u002F\u002Fmedia.kafma.app\u002Fblog\u002Fkafka-javascript-clients\u002Fconsumer.png",2160,[10,1611,1612],{},"Keep the application consumer running, then use Kafma's built-in producer to send controlled test records:",[349,1614,1615,1621,1627],{},[352,1616,1617,1620],{},[13,1618,1619],{},"Manual:"," Send edge-case payloads, tombstones, custom headers, or fixed-partition records.",[352,1622,1623,1626],{},[13,1624,1625],{},"File:"," Load CSV, JSON, or JSONL data for repeatable batch tests. Available with Kafma Pro.",[352,1628,1629,1632],{},[13,1630,1631],{},"Loop:"," Generate continuous test traffic while observing batching, backpressure, and shutdown with in-flight records.",[10,1634,1635],{},[1604,1636],{"alt":1637,"height":1607,"src":1638,"width":1609},"Kafma running a one-second producer loop with regenerated String keys and JSON values while Live shows the resulting records","https:\u002F\u002Fmedia.kafma.app\u002Fblog\u002Fkafka-javascript-clients\u002Floop.png",[326,1640,1642],{"id":1641},"clone-production-shaped-data-for-migration-tests","Clone production-shaped data for migration tests",[10,1644,1645],{},"Simple test data rarely reflects everything in a production topic. Older schema versions, tombstone records with null values, unusual keys, and missing headers can expose migration problems.",[10,1647,1648,1649,1652],{},"Kafma Data Clone copies a bounded time or offset range into a local or staging cluster. With ",[13,1650,1651],{},"Structure + Data",", it can create a missing target topic, register the required schemas, and copy keys, values, timestamps, headers, and tombstones. Optional masking can redact selected sensitive fields.",[10,1654,1655],{},[1604,1656],{"alt":1657,"height":1658,"src":1659,"width":1660},"Kafma cloning selected production topics and masked data to a local cluster",1564,"https:\u002F\u002Fmedia.kafma.app\u002Fchangelog\u002Fv1.0.0\u002Fhomepage-data-clone.png",2740,[33,1662,1664],{"id":1663},"frequently-asked-questions","Frequently asked questions",[326,1666,1668],{"id":1667},"should-an-existing-kafkajs-application-migrate","Should an existing KafkaJS application migrate?",[10,1670,1671],{},"Keep KafkaJS if the application is stable and its feature set and maintenance path remain acceptable. Choose confluent-kafka-javascript when you need KIP-848, GSSAPI\u002FKerberos, first-party Schema Registry support, or commercial support with fewer API changes. Choose Platformatic Kafka when staying pure JavaScript matters and the application can adopt its Node.js requirements and stream-based consumer.",[326,1673,1675],{"id":1674},"is-a-pure-javascript-client-always-easier-to-deploy","Is a pure JavaScript client always easier to deploy?",[10,1677,1678],{},"It usually simplifies packaging by avoiding platform-specific native binaries. Runtime compatibility still matters: Platformatic Kafka requires Node.js 22.22+ or 24.6+, while KafkaJS supports older Node.js versions.",[326,1680,1682],{"id":1681},"which-clients-support-the-kip-848-consumer-group-protocol","Which clients support the KIP-848 consumer group protocol?",[10,1684,1685,1688,1689,1694,1695,1698],{},[150,1686,19],{"href":360,"rel":1687},[154],", confluent-kafka-javascript, and node-rdkafka support KIP-848; KafkaJS does not. KIP-848 requires Kafka 4.0+ brokers. For the two ",[150,1690,1693],{"href":1691,"rel":1692},"https:\u002F\u002Fgithub.com\u002Fconfluentinc\u002Flibrdkafka\u002Fblob\u002Fmaster\u002FINTRODUCTION.md#next-generation-consumer-group-protocol-kip-848",[154],"librdkafka"," clients, set ",[141,1696,1697],{},"group.protocol=consumer","; the classic protocol remains the default. Treat adoption as a consumer migration and test configuration, assignments, rebalances, and commits.",[326,1700,1702],{"id":1701},"does-librdkafka-automatically-make-a-client-faster","Does librdkafka automatically make a client faster?",[10,1704,1705],{},"No. Throughput depends on message size, batching, compression, acknowledgements, network latency, consumer concurrency, and application overhead. Benchmark the complete workload with comparable settings.",[326,1707,1709],{"id":1708},"can-services-using-different-javascript-clients-share-a-topic-or-consumer-group","Can services using different JavaScript clients share a topic or consumer group?",[10,1711,1712],{},"They can share a topic when they agree on key and value serialization, headers, Schema Registry framing, and partitioning assumptions. Consumers sharing a group must also use the same group protocol and compatible assignment behavior; test rebalances and offset commits before mixing clients in production.",[33,1714,1716],{"id":1715},"conclusion","Conclusion",[10,1718,1719],{},"For a new pure-JavaScript service, start with Platformatic Kafka when its Node.js requirements and stream-based consumer fit. Choose confluent-kafka-javascript when you need a KafkaJS-like API, GSSAPI\u002FKerberos, first-party Schema Registry support, or commercial support. Keep KafkaJS or node-rdkafka in a stable existing service unless a missing capability justifies migration.",[10,1721,1722],{},"This guide is maintained by the team behind Kafma.",{"title":1724,"searchDepth":1725,"depth":1725,"links":1726},"",3,[1727,1729,1735,1739,1746,1750,1757],{"id":35,"depth":1728,"text":36},2,{"id":174,"depth":1728,"text":175,"children":1730},[1731,1732,1733,1734],{"id":328,"depth":1725,"text":19},{"id":404,"depth":1725,"text":15},{"id":23,"depth":1725,"text":23},{"id":27,"depth":1725,"text":27},{"id":575,"depth":1728,"text":127,"children":1736},[1737,1738],{"id":589,"depth":1725,"text":590},{"id":817,"depth":1725,"text":818},{"id":1027,"depth":1728,"text":1028,"children":1740},[1741,1742,1743,1744,1745],{"id":1034,"depth":1725,"text":1035},{"id":1093,"depth":1725,"text":1094},{"id":1252,"depth":1725,"text":1253},{"id":1430,"depth":1725,"text":1431},{"id":1530,"depth":1725,"text":1531},{"id":1559,"depth":1728,"text":1560,"children":1747},[1748,1749],{"id":1575,"depth":1725,"text":1576},{"id":1641,"depth":1725,"text":1642},{"id":1663,"depth":1728,"text":1664,"children":1751},[1752,1753,1754,1755,1756],{"id":1667,"depth":1725,"text":1668},{"id":1674,"depth":1725,"text":1675},{"id":1681,"depth":1725,"text":1682},{"id":1701,"depth":1725,"text":1702},{"id":1708,"depth":1725,"text":1709},{"id":1715,"depth":1728,"text":1716},"2026-08-28","Compare KafkaJS, Platformatic Kafka, confluent-kafka-javascript, and node-rdkafka using verified capabilities and scenario recommendations.","md",{},true,null,"\u002Fblog\u002Fkafka-javascript-clients",false,{"title":5,"description":1759},{"loc":1764},"blog\u002Fkafka-javascript-clients",[1770,1771],"Kafka Client Libraries","JavaScript","EB_wRHlKtuIc5i2a7DPbxioLeH2mcNWMPv6qRBAxxCQ",1787926056632]