Build your first HCS powered web app | Hedera Hedera Network Services Token Service Mint and configure tokens and accounts. Consensus Service Verifiable timestamps and ordering of events. Smart Contracts Run Solidity smart contracts. HBAR The Hedera network's native cryptocurrency. Insights How It Works Learn about Hedera from end to end. Explorers View live and historical data on Hedera. Dashboards Analyze network activity and metrics. Network Nodes Understand networks and node types. Devs Start Building Get Started Learn core concepts and build the future. Documentation Review the API and build using your favorite language. Developer Resources Integrations Plugins and microservices for Hedera. Fee Estimator Understand and estimate transaction costs. Open Source Hedera is committed to open, transparent code. Learning Center Learn about web3 and blockchain technologies. Grants Grants & accelerators for your project. Bounties Find bugs. Submit a report. Earn rewards. Ecosystem ECOSYSTEM Hedera Ecosystem Applications, developer tools, network explorers, and more. NFT Ecosystem Metrics Analyze on-chain and market NFT ecosystem metrics. CATEGORIES Web3 Applications Connect into the innovative startups decentralizing the web on Hedera. Enterprise Applications Learn about the Fortune 500 companies decentralizing the web on Hedera. Wallets & Custodians Create a Hedera account to manage HBAR, fungible tokens, and NFTs. Network Explorers Hedera mainnet and testnet graphical network explorers. Developer Tooling Third-party APIs, integrations, and plugins to build apps on Hedera. Grants & Accelerators Boost your project with support from the Hedera ecosystem. Partner Program Explore our partners to bring your vision into reality. Hedera Council Over 30 highly diversified organizations govern Hedera. Use Cases Hedera Solutions Asset Tokenization Studio Open source toolkit for tokenizing assets securely. Stablecoin Studio All-in-one toolkit for stablecoin solutions. Hedera Guardian Auditable carbon markets and traceability. Functional Use Cases Data Integrity & AI Reliable, secure, and ethically governed insights. Sustainability Enabling fair carbon markets with trust. Real-World Asset Tokenization Seamless tokenization of real-world assets and digital at scale. Consumer Engagement & Loyalty Mint, distribute, and redeem loyalty rewards. Decentralized Identity Maintain the lifecycle of credentials. Decentralized Logs Scalable, real-time timestamped events. DeFi Dapps built for the next-generation of finance. NFTs Low, fixed fees. Immutable royalties. Payments Scalable, real-time, and affordable crypto-payments. HBAR Overview Learn about Hedera's token, HBAR. Treasury Management Hedera’s report of the HBAR supply. Governance Decentralized Governance Hedera Council See the world's leading organizations that own Hedera. About Meet Hedera's Board of Directors and team. Journey Watch Hedera's journey to build an empowered digital future for all. Transparent Governance Public Policy Hedera's mission is to inform policy and regulation that impact the industry. Meeting Minutes Immutably recorded on Hedera. Roadmap Follow Hedera's roadmap in its journey to build the future. Resources Company What's New Partners Papers Careers Media Blog Technical Press Podcast Community Events Meetups Store Brand Navigation QUICKSTART Build your first HCS powered web app technical Mar 31, 2020 by Cooper Kunz Developer Evangelist In this tutorial, you will build your first Hedera Consensus Service (HCS) powered application. Specifically, I'll show you how to build a full-stack modern web application, which uses HCS as it’s message queue and a Hedera Mirror Node as a data store. It will use the Hedera JavaScript SDK to run on an Express.js server, which renders a website that is configured to a Socket.io chat client. > Note: If you’re looking for a quick start, jump ahead and view the final codebase here. Prerequisites Hedera Testnet Account Signup at portal.hedera.com Node version > v10 Download at https://nodejs.org/en/download/ NPM version > v6 Download or update at https://docs.npmjs.com/try-the-latest-stable-version-of-npm Background context All messages in the chat application are submitted to Hedera where hashgraph will come to a consensus on a provable, fair order within the topic, with a sequence number, running hash, and consensus timestamp attached. Then the messages will be propagated through a Hedera Mirror Node before displaying to clients connected to the same topic. Although transactions in this demo are signed by a server which acts as a “custodian” for the chat, the code is set up in an easily distributable way where users could host their own chats or run them locally, or implement additional types of key management. One example being the Composer Browser Extension, to further decentralize the application and remove any custodians. Disclaimer: this is a simple demo app intended to demonstrate HCS as a pub-sub programming environment. Use it responsibly! Download & set up the starter project We’ve built a starter project for this application to make it easy for you to get started. This will basically come pre-populated with a non-HCS powered, centralized chat application. This way we can focus on new concepts, like decentralizing the application, rather than on things like the HTML or CSS that make the application look nicer. Let’s get started! You can easily download the starter project from GitHub by running the following command: /* in your terminal */ git clone https://github.com/hashgraph/hedera-hcs-chat-js.git This should download the GitHub repository to your local machine. Now, change directories into the newly cloned GitHub repository. /* in your terminal */ cd hedera-hcs-chat-js Within the correct directory, we will switch to a specific branch on our GitHub repository to get started. /* in your terminal */ git checkout no-hcs Next, we can install the project’s dependencies via npm. /* in your terminal */ npm install After you have successfully installed your npm dependencies, we’ll run our chat application. /* in your terminal */ node server.js Check point: Assuming you're all set up so far, this should open the following window on your local machine. Everything going okay so far? If not, feel free to file an issue, or contact us in Discord. If you type in a few messages & click the send icon, you should see them appear in your chat. You’ll notice that you didn’t configure, or install anything related to Hedera yet. As discussed above, this is just a regular old chat application. There’s not even a database to store messages, let alone a mechanism by which we could trust their authenticity! Let’s fix this, by rearchitecting this app to send messages over HCS. Start decentralizing your chat application with HCS There are a few key parts to building on HCS that may be good to know. Here’s a bit of terminology. Hedera Client - A client which has a valid Account ID, public & private key pairings, for a respective network. These clients send transactions to a Hedera network for consensus. Hedera Node - A computer that reaches consensus on transactions within a given Hedera network. Mirror node client - A client which subscribes to a Hedera Mirror node, in order to receive post-consensus messages. Mirror node - A computer that receives post consensus transactions from other Hedera networks. Topic - A namespace where messages can be published to. Topics can be permissioned, or permissionless, as defined upon their creation. Message - A string of data submitted to a specific topic. Post-consensus, these messages will contain a cryptographically provable “running hash” which builds an unbreakable chain within a topic, among other details. That may seem like a lot, but don’t worry! With the Hedera JavaScript SDK, we make it really easy to manage all of these pieces. The first thing that you’re going to do is install the SDK at version 1.1.4. /* in your terminal */ npm i @hashgraph/[email protected] Your package.json file should now look something like this, assuming everything was successful. /* package.json */ { “name”: “chat”, “version”: “1.0.0", “description”: “”, “main”: “index.js”, “scripts”: { “test”: “echo \“Error: no test specified\” && exit 1" }, “author”: “Cooper Kunz”, “license”: “ISC”, “dependencies”: { “dotenv”: “^8.2.0”, “express”: “^4.17.1”, “inquirer”: “^7.0.4”, “open”: “^7.0.0”, “socket.io”: “^2.3.0”, “text-encoding”: “^0.7.0” }, “repository”: { “type”: “git”, “url”: “git://github.com/Cooper-Kunz/hello-hedera-chat-js.git” } } The first thing that we’re going to want to do with the JavaScript SDK, is configure our client connection. This will build, sign, and execute all of the transactions in this application. Import the `Client` module from the Hedera JavaScript SDK into your server.js file. After importing it, we'll instantiate a new Client for the public Testnet, and provide our Account's ID and the associated private key. Note: if you don't have an Account on the public testnet, sign up at portal.hedera.com. /* within server.js */ /* ... other imports ... */ /* import Hedera JavaScript SDK modules */ const { Client } = require("@hashgraph/sdk"); /* create your Client connection to Hedera's public testnet */ const HederaClient = Client.forTestnet(); HederaClient.setOperator("YOUR-ACCOUNT-ID", "YOUR-PRIVATE-KEY"); /* ... rest of your code ... */ Congratulations! That's actually everything that you need to configure your Hedera Client. Check point: to ensure that you have everything set up properly, and your Hedera JavaScript SDK is allowing you to set your Account as the operator, go ahead and run your chat application again. We're not necessarily doing anything with this Client yet, but if the app runs as before, you're good to continue with the tutorial! Did you run into any issues during this check point? File an issue, or contact us in Discord. Next, we're going to create your first Hedera Consensus Service topic, which will be the "channel" for messages in this app. We will add `ConsensusTopicCreateTransaction` to the list of modules that is being imported from the JavaScript SDK alongside the client. After that, we build a new async function, which will create a transaction. This transaction will create our topic, and then wait until Hedera reaches consensus, to fetch the transaction's receipt. This receipt will contain our new topic ID if it was successful, otherwise hopefully some information about why the transaction failed. /* within server.js */ /* ... other imports ... */ /* import your new Hedera JavaScript SDK modules */ const { Client, ConsensusTopicCreateTransaction } = require("@hashgraph/sdk"); /* create your Client connection to Hedera's public testnet */ /* if you don't have an account & private key, signup at portal.hedera.com */ const HederaClient = Client.forTestnet(); HederaClient.setOperator("YOUR-ACCOUNT-ID", "YOUR-PRIVATE-KEY"); /* create new async function */ async function createNewTopic() { /* create your first HCS topic transaction! */ const txId = await new ConsensusTopicCreateTransaction().execute(HederaClient); await sleep(3000); /* wait for Hedera to reach consensus */ const receipt = await txId.getReceipt(HederaClient); var newTopicId = receipt.getTopicId(); console.log(`Your new topic was created with an ID = ${newTopicId}`); return newTopicId; } /* write a JavaScript function that allows our program to "sleep" */ /* this lets us wait for Hedera to reach consensus, before fetching the transaction receipt */ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } var newTopicId = ""; /* write a new async function that will generate our topic & handoff to run the app */ async function init() { newTopicId = await createNewTopic(); await sleep(9000); /* wait for our new topic to reach a Mirror Node */ runChat(); /* handoff to runChat() here instead of at the end of the file */ } /* ... rest of your code below */ Check point: Go ahead and run your chat application now. It should connect to Hedera's public testnet with your Client & account credentials, and then go on to generate a new HCS topic. However, you'll notice that the rest of the chat application is untouched. In the next step, we'll configure a Mirror Node subscription, and send our chat messages over HCS before displaying to our users. Did you have any issues so far? File an issue, or contact us in Discord. Next, we're going to start "publishing" our chat application's messages over this Hedera Consensus Service topic. Then finally, in the following step, we will "subscribe" to this topic from a Hedera Mirror Node. Add the `ConsensusSubmitMessageTransaction` to the list of modules being imported from the Hedera JavaScript SDK. Then we will put this new transaction type to work within the runChat() function, which is powering our (currently) centralized chat. /* within server.js */ /* updated imports from the Hedera JavaScript SDK */ const { Client, ConsensusTopicCreateTransaction, ConsensusSubmitMessageTransaction } = require("@hashgraph/sdk"); Most of the interesting things in this application happen in the runChat() function. Let's update that now. /* ... within runChat() & server.js ... */ /* When a new chat message is sent to the Express.js Server */ client.on("chat message", function(msg) { /* lets generate an HCS transaction, and send it to Hedera */ try { new ConsensusSubmitMessageTransaction().setTopicId(newTopicId).setMessage(msg).execute(HederaClient); console.log("ConsensusSubmitMessageTransaction", msg); } catch (error) { console.log("ERROR: ConsensusSubmitMessageTransaction", error); } }); /* close client.on() */ /* ... the rest of runChat() & server.js ... */ That's great! Now whenever a user types in a new chat, it's being sent over the Hedera Consensus Service. Check point: Go ahead and run your chat application now. It should now send messages over the Hedera Consensus Service when they are typed into the chat. Feel free to confirm this by looking at a network explorer like HashScan or DragonGlass, and search for your topic ID. Also, when visiting a network explorer, make sure that you're viewing the correct network (mainnet vs. testnet). Did you have any issues so far? File an issue, or contact us in Discord. When building with HCS, we need to wait until Hedera reaches consensus, and persists the message to a Hedera Mirror Node, before displaying to the rest of our clients. This will "close the loop" on our HCS publish-subscribe infrastructure! To do this, we're going to import `MirrorClient` to establish a connection to a Hedera Mirror Node. We're also going to import the `MirrorConsensusTopicQuery` module, which will allow us to query specific topics. We'll put these to work in our runChat() function, which is the final step in this tutorial. Update your code with the following: /* ... within server.js ... */ /* ... other imports ... */ /* import your new Hedera JavaScript SDK modules */ const { Client, ConsensusSubmitMessageTransaction, ConsensusTopicCreateTransaction, MirrorClient, MirrorConsensusTopicQuery } = require("@hashgraph/sdk"); /* create your Mirror node client connection */ const mirrorNodeAddress = new MirrorClient("hcs.testnet.mirrornode.hedera.com:5600"); /* ... other config & functions ... */ /* ... within runChat() ... */ /* subscribe to our Hedera Mirror node */ /* when the Mirror Node receives messages in our topic, send them to our clients */ const TextDecoder = require("text-encoding").TextDecoder; try { new MirrorConsensusTopicQuery().setTopicId(newTopicId).subscribe(mirrorNodeAddress, response => { /* use a node.js package to decode our text responses */ var postHCSMessage = new TextDecoder("utf-8").decode(response["message"]); /* send responses from our Hedera Mirror Node back to our Socket.io clients */ io.emit("chat message", postHCSMessage); }); } catch(error) { console.log("ERROR: MirrorConsensusTopicQuery()", error); } /* ... rest of runChat() & server.js ... */ Final check point: Go ahead and run your chat application now. It should connect to Hedera's public testnet with your Client & account credentials, and then go on to generate a new HCS topic. In this past step, we've also started sending our chat messages over HCS with a new `ConsensusSubmitMessageTransaction` and subscribed to a Mirror Node with a `MirrorConsensusTopicQuery`. After our messages are sent over HCS and received from a Mirror Node, we push these messages out to any Socket.io clients that are listening to our server. You should be able to run the application and have a working chat application, in which all messages are shared over the Hedera Test Network using HCS! Congratulations! You've finished your first steps in taking a chat web app and decentralizing it on Hedera! If you'd like, check out the master branch of the HCS-Chat demo GitHub repository. There are some more features included there for you to check out, including dynamic initialization, and improved data management from the Hedera Mirror Node, which gets displayed to our clients. It looks a bit more like this! There are a lot of things not covered in this tutorial. For instance, decentralized (non-custodial) key management. As a "jumping off point", try implementing something like the Composer Browser Extension, for users to sign their transactions without sending them to a centralized Express.js server. You can also look at the Hedera HCS-SXC demo app for ways to integrate key rotation, message encryption, and more! Did you have any issues with the tutorial? File an issue, or contact us in Discord. Share This Back to blog What is gRPC, gRPC-Web, and Proxies? Ed Marquez Pragmatic Blockchain Design Patterns – Integrating Blockchain into Business Processes Michiel Mulders Zero Cost EthereumTransaction on Success: Hedera's New Fee Model for Relay Operators Oliver Thorn Hedera Adopts Chainlink Standard for Cross-Chain Interoperability To Accelerate Ecosystem Adoption Hedera Team Hedera Developer Highlights March 2025 Michiel Mulders Hedera Release Cycle Overview Ed Marquez View All Posts Sign up for the newsletter CONNECT WITH US Transparency Open Source Audits & Standards Sustainability Commitment Carbon Offsets Governance Hedera Council Public Policy Treasury Management Meeting Minutes LLC Agreement Node Requirements Community Events Meetups HBAR Telegram Developer Discord Twitter Community Support FAQ Network Status Developer Discord StackOverflow Brand Brand Guidelines Built on Hedera Logo Hedera Store About Team Partners Journey Roadmap Careers Contact General Inquiry Public Relations © 2018-2025 Hedera Hashgraph, LLC. All trademarks and company names are the property of their respective owners. All rights in the Deutsche Telekom mark are protected by Deutsche Telekom AG. All rights reserved. Hedera uses the third party marks with permission. Terms of Use  |  Privacy Policy