Building Real-Time React Apps Using GraphQL Subscriptions and GraphQL Database
Hello Developers! GraphQL isn’t just about fetching data efficiently GraphQL Subscriptions in React – into it&#x
2019;s also a powerful solution for real-time communication through its built-in PubSub (Publish-Subscribe) system. Whether you’re building collaborative apps, live dashboards, or notification services, real-time data updates can take your application experience to the next level. GraphQL makes this possible cleanly and elegantly. One of the most exciting features of GraphQL is Subscriptions, which leverage the PubSub model to stream live updates to clients the moment data changes. This eliminates the need for constant polling or complicated client-side logic. But to truly unlock its potential, you need a solid understanding of how PubSub works under the hood in a GraphQL-powered database environment. In this article, we’ll explore how to implement GraphQL subscriptions in React using the GraphQL Database Language, enabling you to build real-time, responsive frontend applications with ease.Table of contents
- Building Real-Time React Apps Using GraphQL Subscriptions and GraphQL Database
- Introduction to Using GraphQL Subscriptions in React with a GraphQL Database
- Key Features of GraphQL Subscriptions in React with a GraphQL Database Language
- Defining a GraphQL Subscription on the Server
- Setting up Apollo Client with Subscriptions in React
- Subscribing to Data in a React Component
- Triggering Subscription Events via Mutation
- Why do we need to Use GraphQL Subscriptions in React with a GraphQL Database Language?
- 1. Efficient Real-Time Data Updates
- 2. Reduced Server and Network Load
- 3. Seamless Integration with React
- 4. Enhanced User Experience and Engagement
- 5. Tight Backend-Frontend Synchronization via PubSub
- 6. Simplified Client-Side Logic
- 7. Scalability for Modern Applications
- 8. Flexibility to Handle Complex Real-Time Scenarios
- Example of Using GraphQL Subscriptions in React with a GraphQL Database Language
- 1. Setting Up a Basic GraphQL Subscription on the Backend
- 2. Publishing Events When Data Changes (Backend Mutation Example)
- 3. React Frontend Setup for Subscriptions with Apollo Client
- 4. Using the Subscription in React Components
- Advantages of Using GraphQL Subscriptions in React with a GraphQL Database Language
- Disadvantages of Using GraphQL Subscriptions in React with a GraphQL Database Language
- Future Development and Enhancement of Using GraphQL Subscriptions in React with a GraphQL Database Language
Introduction to Using GraphQL Subscriptions in React with a GraphQL Database
Real-time updates have become essential for building dynamic and engaging web applications. With GraphQL Subscriptions, you can effortlessly push live data changes from your backend to your React frontend, creating seamless user experiences without relying on inefficient polling. By integrating GraphQL Subscriptions with a GraphQL database, developers can leverage a powerful PubSub system that keeps your app data in sync instantly. This introduction will guide you through the basics of using GraphQL Subscriptions in React with a GraphQL database, helping you build responsive, real-time applications with ease.
What Are GraphQL Subscriptions in React with a GraphQL Database?
GraphQL Subscriptions are a powerful feature of GraphQL that enable real-time communication between the server and clients. Unlike standard queries and mutations, which follow a request-response pattern, subscriptions create a persistent connection usually through WebSockets allowing the server to send data updates to clients instantly when specific events occur.
Key Features of GraphQL Subscriptions in React with a GraphQL Database Language
- Real-Time Data Updates:GraphQL Subscriptions enable your React application to receive instant updates from the backend whenever data changes occur. This eliminates the need for manual refreshes or polling, allowing your UI to stay in sync with the latest data effortlessly. Real-time updates are essential for applications like chat systems, live notifications, and dashboards.
- Persistent WebSocket Connection: Subscriptions rely on a persistent WebSocket connection between the React client and the GraphQL server. This continuous connection allows the server to push data immediately when events happen, making communication more efficient than traditional HTTP requests. WebSockets reduce latency and improve responsiveness.
- PubSub System Integration: Within a GraphQL Database environment, subscriptions leverage a Publish-Subscribe (PubSub) system that listens to database events. When a change happens, the PubSub mechanism broadcasts these events to all subscribed clients. This seamless backend integration ensures consistent and accurate real-time data flow.
- Simplified Frontend Logic: Using subscriptions in React reduces the complexity of client-side code needed to handle real-time updates. Instead of implementing timers or manual fetch requests, React components can subscribe to data streams and automatically re-render when new data arrives. This leads to cleaner, more maintainable frontend code.
- Scalability and Performance: GraphQL Subscriptions are designed to efficiently handle multiple simultaneous connections and data streams. By pushing only relevant updates to subscribed clients, they optimize network and server resources. This makes building scalable real-time applications practical, even with large numbers of users.
- Fine-Grained Data Control: GraphQL Subscriptions allow clients to specify exactly which data they want to receive updates for. This precise querying reduces unnecessary data transfer and ensures clients get only the relevant information they need. Such control improves both efficiency and user experience by minimizing bandwidth and processing overhead.
- Seamless Integration with React Ecosystem: Subscriptions fit naturally into the React ecosystem, especially when used with popular libraries like Apollo Client or Relay. These tools provide hooks and components that make managing subscription data straightforward, helping developers handle connection states, error handling, and data updates with minimal boilerplate.
- Enhanced User Engagement: By delivering real-time updates directly to the user interface, GraphQL Subscriptions help create more interactive and engaging applications. Users receive immediate feedback on changes, which is crucial for apps like social media, collaborative tools, and live sports updates, where timely information significantly enhances the user experience.
- Reduced Backend Load Compared to Polling: Traditional polling techniques require clients to repeatedly ask the server for updates, increasing server load and network traffic. Subscriptions, on the other hand, use event-driven updates that only send data when changes occur, reducing unnecessary requests and improving backend efficiency.
- Support for Complex Event Handling: GraphQL Subscriptions can be designed to listen for complex and custom backend events beyond simple data changes. This flexibility allows developers to implement advanced real-time features such as multi-user collaboration, alert systems, or transaction monitoring, all while keeping the frontend reactive and up-to-date.
Defining a GraphQL Subscription on the Server
First, you need to define a subscription on your GraphQL server schema. For example, a subscription that sends live updates whenever a new message is created:
type Subscription {
messageAdded: Message
}
type Message {
id: ID!
content: String!
author: String!
}
The resolver might look like this
const { PubSub } = require('graphql-subscriptions');
const pubsub = new PubSub();
const resolvers = {
Subscription: {
messageAdded: {
subscribe: () => pubsub.asyncIterator(['MESSAGE_ADDED']),
},
},
Mutation: {
addMessage: (parent, { content, author }) => {
const message = { id: generateId(), content, author };
pubsub.publish('MESSAGE_ADDED', { messageAdded: message });
return message;
},
},
};
Setting up Apollo Client with Subscriptions in React
To handle subscriptions in React, you need to configure Apollo Client with WebSocket support:
import { ApolloClient, InMemoryCache, split, HttpLink } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';
import { getMainDefinition } from '@apollo/client/utilities';
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql',
});
const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/graphql`,
options: { reconnect: true },
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink
);
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
Subscribing to Data in a React Component
Now, use Apollo’s useSubscription
hook to listen for live updates in a React component:
import { gql, useSubscription } from '@apollo/client';
const MESSAGE_ADDED = gql`
subscription OnMessageAdded {
messageAdded {
id
content
author
}
}
`;
function Messages() {
const { data, loading, error } = useSubscription(MESSAGE_ADDED);
if (loading) return <p>Loading messages...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h2>New Message</h2>
<p>
<strong>{data.messageAdded.author}:</strong> {data.messageAdded.content}
</p>
</div>
);
}
Triggering Subscription Events via Mutation
You can trigger subscription updates from mutations. For example, a form to add messages:
import { gql, useMutation } from '@apollo/client';
import { useState } from 'react';
const ADD_MESSAGE = gql`
mutation AddMessage($content: String!, $author: String!) {
addMessage(content: $content, author: $author) {
id
content
author
}
}
`;
function MessageForm() {
const [content, setContent] = useState('');
const [author, setAuthor] = useState('');
const [addMessage] = useMutation(ADD_MESSAGE);
const handleSubmit = (e) => {
e.preventDefault();
addMessage({ variables: { content, author } });
setContent('');
};
return (
<form onSubmit={handleSubmit}>
<input
value={author}
onChange={(e) => setAuthor(e.target.value)}
placeholder="Author"
required
/>
<input
value={content}
onChange={(e) => setContent(e.target.value)}
placeholder="Message"
required
/>
<button type="submit">Send</button>
</form>
);
}
Why do we need to Use GraphQL Subscriptions in React with a GraphQL Database Language?
In modern web applications, real-time data updates are crucial for delivering dynamic and responsive user experiences. Traditional methods like polling where the client repeatedly requests updated data are inefficient and can strain both client and server resources. GraphQL Subscriptions provide an elegant solution by enabling the server to push data updates directly to React clients as soon as changes occur, without the need for constant requests.
1. Efficient Real-Time Data Updates
GraphQL Subscriptions enable your React app to receive real-time data updates instantly when the backend data changes. Unlike traditional polling methods that continuously ask the server for updates, subscriptions push data only when necessary. This reduces unnecessary network requests, saving bandwidth and improving app responsiveness. Real-time updates are crucial for applications like chat apps, live dashboards, or collaborative tools where users expect immediate feedback.
2. Reduced Server and Network Load
Polling mechanisms generate repeated requests, which can overload the server and consume excessive network resources, especially with many users. GraphQL Subscriptions maintain a single persistent connection (typically via WebSockets), allowing the server to push updates only when data changes occur. This event-driven model lowers server load, minimizes network traffic, and ensures scalable performance even under heavy user loads.
3. Seamless Integration with React
React’s component-based architecture works well with GraphQL Subscriptions. Using libraries like Apollo Client, developers can easily manage subscription data streams through hooks such as useSubscription
. This integration allows React components to automatically update and re-render with new data, making UI state management simpler and more maintainable. Developers avoid complex manual state handling and polling logic.
4. Enhanced User Experience and Engagement
Real-time data synchronization via GraphQL Subscriptions provides users with up-to-date information without needing page refreshes. This immediacy enhances user engagement by making apps feel faster and more interactive. Whether it’s live sports scores, collaborative document editing, or notification alerts, users benefit from timely updates that keep them connected and informed.
5. Tight Backend-Frontend Synchronization via PubSub
A GraphQL Database equipped with a PubSub system listens for changes in the database and broadcasts these events to subscribed clients. This tight integration ensures the React frontend stays perfectly synchronized with backend data in real time. Such seamless communication is vital for applications where data consistency and immediacy are priorities, reducing the chance of stale or outdated information.
6. Simplified Client-Side Logic
Subscriptions simplify the client-side architecture by offloading the responsibility of tracking data changes to the server. Instead of writing complex timers or repeated fetch calls, React components subscribe to data streams and automatically update as events arrive. This leads to cleaner, more readable, and easier-to-maintain frontend code, saving development time and reducing bugs.
7. Scalability for Modern Applications
Because GraphQL Subscriptions use an event-driven, push-based communication model, they support handling large numbers of concurrent users efficiently. By pushing only relevant updates and maintaining persistent connections, applications can scale better compared to frequent polling or manual refreshes. This scalability makes subscriptions suitable for modern apps with growing user bases and real-time requirements.
8. Flexibility to Handle Complex Real-Time Scenarios
GraphQL Subscriptions offer the flexibility to listen for a wide range of events beyond simple data changes. Whether it’s monitoring complex workflows, multi-user interactions, or conditional triggers within your GraphQL Database, subscriptions can be tailored to deliver precise updates to React clients. This adaptability allows developers to build sophisticated real-time features like collaborative editing, live auctions, or monitoring systems, all while keeping the frontend perfectly synchronized without heavy lifting on the client side.
Example of Using GraphQL Subscriptions in React with a GraphQL Database Language
GraphQL Subscriptions allow your React application to receive real-time updates by maintaining an open connection to the server, typically using WebSockets. This means whenever data changes in your GraphQL database, the server can immediately push those changes to subscribed clients without the need for the clients to repeatedly ask for updates. This event-driven model is especially useful for applications requiring live data, such as chat apps, notifications, or collaborative tools.
1. Setting Up a Basic GraphQL Subscription on the Backend
First, define a subscription in your GraphQL schema and set up a PubSub system to publish updates. Here’s a simple example using Apollo Server with graphql-subscriptions:
const { ApolloServer, gql, PubSub } = require('apollo-server');
const pubsub = new PubSub();
const MESSAGE_ADDED = 'MESSAGE_ADDED';
const typeDefs = gql`
type Message {
id: ID!
content: String!
}
type Query {
messages: [Message!]
}
type Subscription {
messageAdded: Message
}
`;
const messages = [];
const resolvers = {
Query: {
messages: () => messages,
},
Subscription: {
messageAdded: {
subscribe: () => pubsub.asyncIterator([MESSAGE_ADDED]),
},
},
};
const server = new ApolloServer({ typeDefs, resolvers });
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
- We define a
messageAdded
subscription that clients can subscribe to. - When a new message is added, an event is published to
MESSAGE_ADDED
topic. - Clients connected via WebSocket will receive these real-time updates.
2. Publishing Events When Data Changes (Backend Mutation Example)
To trigger updates, publish events in your mutation resolvers:
const resolvers = {
Mutation: {
addMessage: (_, { content }) => {
const message = { id: messages.length + 1, content };
messages.push(message);
pubsub.publish(MESSAGE_ADDED, { messageAdded: message });
return message;
},
},
Subscription: {
messageAdded: {
subscribe: () => pubsub.asyncIterator([MESSAGE_ADDED]),
},
},
};
- The
addMessage
mutation adds a new message and immediately publishes amessageAdded
event. - All subscribed clients receive the new message in real time.
3. React Frontend Setup for Subscriptions with Apollo Client
To receive subscription updates in React, use Apollo Client’s useSubscription
hook. First, configure Apollo Client with a WebSocket link:
import { ApolloClient, InMemoryCache, split, HttpLink } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';
import { getMainDefinition } from '@apollo/client/utilities';
const httpLink = new HttpLink({
uri: 'http://localhost:4000/graphql',
});
const wsLink = new WebSocketLink({
uri: `ws://localhost:4000/graphql`,
options: { reconnect: true },
});
const splitLink = split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
wsLink,
httpLink,
);
const client = new ApolloClient({
link: splitLink,
cache: new InMemoryCache(),
});
- HTTP link handles queries/mutations.
- WebSocket link handles subscriptions.
- The
split
function routes operations to the appropriate link based on their type.
4. Using the Subscription in React Components
Use the useSubscription
hook to listen for new messages and update the UI in real time:
import React from 'react';
import { gql, useSubscription } from '@apollo/client';
const MESSAGE_ADDED_SUBSCRIPTION = gql`
subscription OnMessageAdded {
messageAdded {
id
content
}
}
`;
function Messages() {
const { data, loading } = useSubscription(MESSAGE_ADDED_SUBSCRIPTION);
if (loading) return <p>Loading...</p>;
return (
<div>
<h2>New Messages:</h2>
{data && <p>{data.messageAdded.content}</p>}
</div>
);
}
export default Messages;
- The component subscribes to
messageAdded
updates. - Whenever a new message is published, the component receives it instantly and re-renders showing the new content.
Advantages of Using GraphQL Subscriptions in React with a GraphQL Database Language
These are the Advantages of Using GraphQL Subscriptions in React with a GraphQL Database Language:
- Real-Time Data Updates: GraphQL Subscriptions enable your React app to receive live updates instantly whenever data changes in the backend. This means users see fresh data without needing to refresh the page or trigger manual reloads. This real-time capability is essential for building dynamic applications like chat apps, live dashboards, or notifications where up-to-date information improves user engagement and experience.
- Efficient Network Usage: Unlike traditional polling techniques that repeatedly request data at intervals, GraphQL Subscriptions maintain a single persistent WebSocket connection to push updates only when necessary. This reduces unnecessary network traffic and server load, improving overall application performance and scalability. It also helps conserve client device resources, which is especially important for mobile and low-bandwidth environments.
- Seamless Integration with React: React’s component-driven architecture pairs naturally with GraphQL Subscriptions, especially when using libraries like Apollo Client. The
useSubscription
hook allows components to effortlessly listen for updates and re-render when new data arrives. This tight integration simplifies state management and eliminates the need for complex custom logic to handle real-time data, making development faster and code more maintainable. - Enhanced User Experience: By delivering updates instantly, subscriptions help create highly interactive and responsive applications. Users get immediate feedback on changes such as new messages, notifications, or data changes, which makes the app feel more alive and engaging. This improved responsiveness can lead to higher user satisfaction and retention, essential for competitive modern web and mobile apps.
- Scalability for Modern Applications: Because subscriptions use an event-driven model with persistent connections, they scale better for apps with many concurrent users compared to frequent polling. The server pushes only relevant updates to subscribed clients, reducing unnecessary processing and bandwidth usage. This efficient communication model helps support large-scale real-time applications without degrading performance.
- Reduced Client-Side Complexity: GraphQL Subscriptions offload much of the real-time data management to the server and transport layer. React components simply subscribe to the data stream and receive updates automatically. This reduces the complexity of client-side code by avoiding manual polling, timers, or repeated fetch requests, leading to cleaner, more maintainable frontend codebases.
- Tight Backend-Frontend Synchronization: When combined with a GraphQL database supporting PubSub or event notifications, subscriptions ensure that the React frontend is perfectly synchronized with backend data changes. This tight coupling reduces the chances of stale or inconsistent data on the client side, improving data integrity and user trust in the application’s accuracy.
- Improved Developer Productivity: GraphQL Subscriptions streamline the process of adding real-time features, allowing developers to focus on building functionality rather than managing complex state synchronization or socket connections. With tools like Apollo Client’s built-in hooks and straightforward subscription syntax, developers can implement live updates quickly, reducing development time and minimizing bugs associated with real-time data handling.
- Customizable and Flexible Subscriptions: Subscriptions can be tailored to specific data events or filters, enabling apps to receive only the relevant updates they need. This customization reduces data noise and optimizes performance by limiting the subscription scope. For example, a chat app can subscribe to messages only from certain channels or users, ensuring that clients handle precisely the data they require.
- Future-Proof Architecture for Modern Apps: Integrating GraphQL Subscriptions establishes a robust foundation for building interactive applications that can evolve easily as real-time requirements grow. With real-time communication baked into the architecture, developers can add more live features like collaborative editing, live analytics, or instant alerts without major rewrites, ensuring the app remains modern and competitive.
Disadvantages of Using GraphQL Subscriptions in React with a GraphQL Database Language
These are the Disadvantages of Using GraphQL Subscriptions in React with a GraphQL Database Language:
- Increased Complexity in Backend Setup: Implementing GraphQL Subscriptions requires additional backend infrastructure, such as WebSocket servers and PubSub mechanisms. This setup is more complex compared to simple query and mutation resolvers, often needing extra configuration and maintenance, which can slow down development and require specialized knowledge.
- Scalability Challenges with Many Clients: Maintaining persistent WebSocket connections for a large number of clients can strain server resources. Unlike stateless HTTP requests, WebSocket connections consume memory and bandwidth continuously, potentially leading to scalability bottlenecks if not carefully managed with load balancing and connection handling strategies.
- Limited Support Across Platforms and Tools: Not all GraphQL clients or platforms fully support subscriptions or WebSocket connections. This inconsistency can limit where and how you can implement subscriptions, sometimes forcing fallback solutions or complex workarounds, especially in environments with strict network policies or older browsers.
- Debugging and Monitoring Difficulties: Real-time subscriptions introduce complexity in tracking data flow and debugging issues. Since updates are pushed asynchronously, errors or performance problems can be harder to detect and diagnose compared to traditional request-response models, requiring more advanced logging and monitoring tools.
- Increased Client-Side Resource Usage: Subscriptions maintain an open connection and constantly listen for events, which can increase CPU and memory usage on the client side, especially on mobile devices or low-powered hardware. This persistent activity might affect battery life and overall app performance if not optimized carefully.
- Network Stability Dependency: GraphQL Subscriptions rely heavily on stable WebSocket connections. Any network interruptions or unstable internet can cause the subscription to drop, leading to missed updates or the need to implement reconnection logic. This dependency can affect user experience, especially on mobile networks with fluctuating connectivity.
- Security Concerns: Maintaining persistent WebSocket connections opens up potential security risks such as unauthorized access, data interception, or denial-of-service attacks. Securing subscriptions requires additional layers like authentication, authorization, and encrypted communication, adding to the development and operational overhead.
- Increased Server Complexity and Cost: Running subscription servers requires more resources and infrastructure compared to simple HTTP APIs. This includes scaling WebSocket servers, managing connection states, and ensuring high availability. Consequently, the operational costs can rise, especially for applications with many concurrent users needing real-time updates.
- Compatibility Issues with Caching
Subscriptions deliver real-time data and typically bypass traditional HTTP caching layers, which are designed for request-response models. This can complicate caching strategies, requiring custom solutions to ensure data consistency without sacrificing performance. - Learning Curve for Developers: Implementing and managing GraphQL subscriptions introduces a learning curve for developers unfamiliar with WebSockets, event-driven architectures, and asynchronous data handling. This can slow down the development process initially and necessitate training or hiring specialized talent.
Future Development and Enhancement of Using GraphQL Subscriptions in React with a GraphQL Database Language
Following are the Future Development and Enhancement of Using GraphQL Subscriptions in React with a GraphQL Database Language:
- Improved Subscription Protocols: Future developments may focus on optimizing the underlying protocols for subscriptions, such as enhancing WebSocket efficiency or introducing alternative transport layers like HTTP/2 or WebTransport. These improvements can reduce latency, improve reliability, and offer better compatibility with modern web infrastructure, making real-time updates faster and more stable.
- Enhanced Security Features: As adoption grows, security enhancements will be critical for protecting subscription data streams. Future improvements could include more robust encryption standards, better authentication methods like token refresh mechanisms, and fine-grained authorization controls to ensure only authorized clients receive specific subscription updates.
- Serverless and Edge Computing Integration: Advancements will likely include better support for serverless architectures and edge computing environments. Running subscriptions closer to users on edge nodes can dramatically reduce latency and improve scalability. This trend will enable real-time apps to deliver faster and more reliable data updates regardless of geographic location.
- Smarter Client-Side Management: Client libraries like Apollo Client are expected to evolve with smarter caching, automatic reconnection strategies, and adaptive subscription handling based on network conditions. These enhancements will simplify developers’ work by making subscriptions more resilient to network changes and more efficient in resource usage.
- Broader Ecosystem and Tooling Support: The GraphQL ecosystem will continue to grow with better support for subscriptions across various frameworks, databases, and cloud providers. This expansion will bring more tools for monitoring, debugging, and visualizing real-time data flows, making it easier for teams to implement and maintain subscription-based features.
- Integration with AI and Machine Learning: Future enhancements might include integrating subscriptions with AI and ML models to provide predictive real-time updates. For example, subscriptions could trigger personalized content or notifications based on user behavior patterns, enhancing user engagement and making applications smarter and more adaptive.
- Standardization and Best Practices: As subscriptions mature, industry-wide standards and best practices for implementing, scaling, and securing subscriptions will emerge. This will help developers avoid common pitfalls, adopt consistent patterns, and leverage community-vetted solutions, accelerating the adoption of real-time features in React apps.
- Expanded Use Cases and Adoption: Real-time data needs will continue to grow beyond traditional use cases like chat or notifications. We can expect subscriptions to be applied in more complex domains such as collaborative editing, live gaming, IoT monitoring, and financial trading, driving innovation in how GraphQL subscriptions are used and optimized.
- Improved Performance and Scalability: Future developments will aim to optimize server and client performance for handling massive numbers of concurrent subscriptions. This includes better load balancing, distributed PubSub systems, and resource-efficient architectures that allow real-time features to scale seamlessly for enterprise-grade applications.
- Enhanced Developer Experience: Tooling improvements will focus on simplifying the developer experience around subscriptions. Enhanced debugging tools, better error handling, comprehensive documentation, and intuitive APIs will empower developers to build and maintain real-time features more easily and with fewer bugs.
Discover more from PiEmbSysTech
Subscribe to get the latest posts sent to your email.