<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ABDULKAREEM</title>
    <description>The latest articles on DEV Community by ABDULKAREEM (@abdulkareemtpm).</description>
    <link>https://dev.to/abdulkareemtpm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F324339%2F0fd3ba4d-8771-4ef0-b8c9-17ff9748d97c.jpg</url>
      <title>DEV Community: ABDULKAREEM</title>
      <link>https://dev.to/abdulkareemtpm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdulkareemtpm"/>
    <language>en</language>
    <item>
      <title>I Built an Open-Source AI Tool That Turns Any Codebase Into Deep Engineering Documentation (Runs 100% Locally)</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Tue, 24 Feb 2026 08:31:43 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/i-built-an-open-source-ai-tool-that-turns-any-codebase-into-deep-engineering-documentation-runs-5h89</link>
      <guid>https://dev.to/abdulkareemtpm/i-built-an-open-source-ai-tool-that-turns-any-codebase-into-deep-engineering-documentation-runs-5h89</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F216n5jphqtfmyun551hq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F216n5jphqtfmyun551hq.png" alt="KT Studio – Turn Any Codebase into Deep Documentation" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most engineering problems aren’t about writing code.&lt;/p&gt;

&lt;p&gt;Understanding code is harder than writing it.&lt;/p&gt;

&lt;p&gt;Onboarding a new developer.&lt;br&gt;&lt;br&gt;
Taking over a legacy repository.&lt;br&gt;&lt;br&gt;
Preparing proper knowledge transfer before someone exits.&lt;/p&gt;

&lt;p&gt;The code exists.&lt;br&gt;&lt;br&gt;
The knowledge usually doesn’t.&lt;/p&gt;

&lt;p&gt;So I built something to fix that.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Introducing KT Studio
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;KT Studio&lt;/strong&gt; is an open-source, local-first web application that scans your repository and generates deep, structured engineering documentation using a local Ollama model.&lt;/p&gt;

&lt;p&gt;No cloud.&lt;br&gt;&lt;br&gt;
No code uploads.&lt;br&gt;&lt;br&gt;
No external APIs.&lt;/p&gt;

&lt;p&gt;Everything runs entirely on your machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/tpmabdulkareem/KT-Studio" rel="noopener noreferrer"&gt;https://github.com/tpmabdulkareem/KT-Studio&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What It Actually Does
&lt;/h2&gt;

&lt;p&gt;KT Studio analyzes your project and generates a structured documentation site with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Architecture overview (with Mermaid diagrams)&lt;/li&gt;
&lt;li&gt;✅ Quick start guide (real setup commands from your repo)&lt;/li&gt;
&lt;li&gt;✅ API reference (parsed from routes)&lt;/li&gt;
&lt;li&gt;✅ Database layer explanation&lt;/li&gt;
&lt;li&gt;✅ Environment variable breakdown&lt;/li&gt;
&lt;li&gt;✅ CI/CD &amp;amp; deployment notes&lt;/li&gt;
&lt;li&gt;✅ AI integrations detection (OpenAI, Ollama, LangChain, etc.)&lt;/li&gt;
&lt;li&gt;✅ Testing strategy&lt;/li&gt;
&lt;li&gt;✅ Troubleshooting guide&lt;/li&gt;
&lt;li&gt;✅ Ownership &amp;amp; risk areas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a generic summary.&lt;br&gt;&lt;br&gt;
It reads your project structure and generates &lt;strong&gt;repo-aware&lt;/strong&gt; documentation.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔒 Why Local-First AI?
&lt;/h2&gt;

&lt;p&gt;Many teams can’t upload proprietary repositories to cloud AI tools.&lt;/p&gt;

&lt;p&gt;KT Studio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses Node.js filesystem scanning&lt;/li&gt;
&lt;li&gt;Skips &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;dist&lt;/code&gt;, and build artifacts&lt;/li&gt;
&lt;li&gt;Ignores &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.pem&lt;/code&gt;, terraform secrets&lt;/li&gt;
&lt;li&gt;Redacts potential credentials automatically&lt;/li&gt;
&lt;li&gt;Runs via Ollama at &lt;code&gt;http://127.0.0.1:11434&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your code never leaves your machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗 Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Next.js (App Router) + TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tailwind CSS + shadcn/ui&lt;/li&gt;
&lt;li&gt;SQLite via Prisma&lt;/li&gt;
&lt;li&gt;Ollama (default: &lt;code&gt;qwen3-coder:30b&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;react-markdown + Mermaid.js&lt;/li&gt;
&lt;li&gt;Server-Sent Events (SSE) for real-time streaming&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚡ Real Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Developer Onboarding
&lt;/h3&gt;

&lt;p&gt;Generate a project blueprint before a new developer joins.&lt;/p&gt;

&lt;h3&gt;
  
  
  Knowledge Transfer
&lt;/h3&gt;

&lt;p&gt;Senior dev leaving? Generate structured KT docs in minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Codebase Audits
&lt;/h3&gt;

&lt;p&gt;Understand inherited repositories faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI-Heavy Projects
&lt;/h3&gt;

&lt;p&gt;Automatically detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Model usage&lt;/li&gt;
&lt;li&gt;Prompt templates&lt;/li&gt;
&lt;li&gt;Embedding pipelines&lt;/li&gt;
&lt;li&gt;RAG-style integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Consulting &amp;amp; Freelancing
&lt;/h3&gt;

&lt;p&gt;Deliver solid documentation with project handoffs.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 How To Run It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js v18+&lt;/li&gt;
&lt;li&gt;Ollama running locally (&lt;code&gt;http://127.0.0.1:11434&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;An Ollama model installed (defaults to &lt;code&gt;qwen3-coder:30b&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Install &amp;amp; Start
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install
&lt;/span&gt;npx prisma db push
npx prisma generate
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open: &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generate Docs (Local Mode)&lt;br&gt;
    1.  Ensure Ollama is running&lt;br&gt;
    2.  Click New Project&lt;br&gt;
    3.  Choose Local Folder and enter the absolute path&lt;br&gt;
    4.  Click Start Generation&lt;br&gt;
    5.  After it finishes, click View Documentation&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🌍 What’s Next?&lt;/p&gt;

&lt;p&gt;Planned expansions:&lt;br&gt;
    • Git repository import mode&lt;br&gt;
    • Vector-based semantic indexing&lt;br&gt;
    • Incremental regeneration&lt;br&gt;
    • Architecture diffing between versions&lt;br&gt;
    • Plugin-based documentation sections&lt;br&gt;
    • Team collaboration mode&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;🤝 Looking for Collaborators&lt;/p&gt;

&lt;p&gt;If you’re interested in:&lt;br&gt;
    • AI-powered developer tools&lt;br&gt;
    • Local LLM systems&lt;br&gt;
    • Repo intelligence&lt;br&gt;
    • Developer productivity&lt;br&gt;
    • Open-source infrastructure&lt;/p&gt;

&lt;p&gt;I’d love to collaborate.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/tpmabdulkareem/KT-Studio" rel="noopener noreferrer"&gt;https://github.com/tpmabdulkareem/KT-Studio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⸻&lt;/p&gt;

&lt;p&gt;💡 Bigger Vision&lt;/p&gt;

&lt;p&gt;What if every repository could explain itself?&lt;/p&gt;

&lt;p&gt;What if onboarding took hours instead of weeks?&lt;/p&gt;

&lt;p&gt;What if knowledge transfer wasn’t dependent on memory?&lt;/p&gt;

&lt;p&gt;That’s what KT Studio is trying to solve.&lt;/p&gt;

&lt;p&gt;Let’s make codebases self-explanatory.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ollama</category>
      <category>nextjs</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Building a Scalable Backend with NestJS Microservices: A Blueprint for Modern Architecture</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Wed, 09 Apr 2025 05:24:38 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/building-a-scalable-backend-with-nestjs-microservices-a-blueprint-for-modern-architecture-4b7a</link>
      <guid>https://dev.to/abdulkareemtpm/building-a-scalable-backend-with-nestjs-microservices-a-blueprint-for-modern-architecture-4b7a</guid>
      <description>&lt;p&gt;In today’s fast-evolving tech landscape, scalability, modularity, and performance are the cornerstones of a robust backend system. Whether you’re building for a startup or an enterprise-grade application, having an architecture that can grow with your needs is non-negotiable. That’s why I’m excited to share a sample project I’ve been working on: a &lt;strong&gt;highly scalable backend architecture&lt;/strong&gt; built using NestJS microservices. This repository brings together some of the most powerful tools and patterns in modern development—Repository Pattern, Prisma ORM, GraphQL, and gRPC with Protobuf—to create a blueprint for adaptable, production-ready systems.&lt;/p&gt;

&lt;p&gt;You can explore the full implementation here: &lt;a href="https://github.com/tpmabdulkareem/NestJS-Microservice-Backend-with-Repository-Pattern-Prisma-GraphQL-gRPC" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s dive into what makes this project tick and why it might be the perfect starting point for your next backend endeavor.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why NestJS Microservices?
&lt;/h3&gt;

&lt;p&gt;NestJS is a progressive Node.js framework that combines the best of TypeScript, object-oriented programming, and functional paradigms. Its built-in support for microservices makes it an ideal choice for distributed systems. Unlike monolithic architectures, microservices allow you to break your application into smaller, independent services that can be developed, deployed, and scaled separately. This project leverages NestJS’s microservices capabilities to demonstrate how you can achieve modularity without sacrificing performance or maintainability.&lt;/p&gt;




&lt;h3&gt;
  
  
  Core Features of the Architecture
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Repository Pattern for Clean Data Access&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The Repository Pattern is a time-tested approach to abstracting data access logic from your business logic. In this project, I’ve implemented it to create a clean separation between the database layer and the service layer. This not only improves testability (think mocking repositories for unit tests) but also makes the codebase easier to maintain as it grows. Whether you’re swapping out databases or adding new data sources, the Repository Pattern keeps your code flexible and future-proof.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Prisma ORM for Database Magic&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Speaking of databases, this project integrates &lt;strong&gt;Prisma&lt;/strong&gt;, a next-generation ORM that simplifies database interactions with a type-safe, intuitive API. Prisma handles everything from schema migrations to query generation, allowing you to focus on building features rather than wrestling with SQL. In this setup, Prisma powers the data layer, making it seamless to connect to PostgreSQL, MySQL, or any other supported database.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;GraphQL for Flexible API Queries&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;For the API layer, I’ve opted for &lt;strong&gt;GraphQL&lt;/strong&gt; over traditional REST. Why? GraphQL’s ability to let clients request exactly the data they need eliminates over-fetching and under-fetching issues common in REST APIs. With NestJS’s built-in GraphQL module, setting up a schema-first or code-first approach is a breeze. This project showcases how GraphQL can serve as the glue between your frontend and microservices, offering a unified and efficient querying experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. &lt;strong&gt;gRPC with Protobuf for High-Performance Communication&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Microservices need to talk to each other, and that’s where &lt;strong&gt;gRPC&lt;/strong&gt; shines. Paired with Protocol Buffers (Protobuf), gRPC enables lightning-fast, strongly-typed communication between services. Unlike REST, which relies on JSON over HTTP, gRPC uses binary serialization and HTTP/2, making it perfect for performance-critical systems. In this repository, I’ve set up gRPC to handle cross-service communication, demonstrating how to define service contracts and implement them in a real-world scenario.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Makes This Project Scalable?
&lt;/h3&gt;

&lt;p&gt;Scalability isn’t just about handling more users—it’s about designing a system that can evolve. Here’s how this architecture delivers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modular Design&lt;/strong&gt;: Each microservice is self-contained, allowing you to scale specific components independently based on demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technology Agnostic&lt;/strong&gt;: The Repository Pattern and Prisma make it easy to swap databases or add new services without rewriting core logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Optimized&lt;/strong&gt;: gRPC ensures low-latency communication, while GraphQL reduces API overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensible&lt;/strong&gt;: NestJS’s dependency injection and modular structure mean you can plug in new features or services with minimal friction.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Who Is This For?
&lt;/h3&gt;

&lt;p&gt;This project is designed as a starting point for developers and teams looking to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a modern backend from scratch with best practices in mind.&lt;/li&gt;
&lt;li&gt;Experiment with microservices in a controlled, sample environment.&lt;/li&gt;
&lt;li&gt;Learn how to integrate cutting-edge tools like Prisma, GraphQL, and gRPC in a real-world context.&lt;/li&gt;
&lt;li&gt;Adapt a scalable architecture to their specific production needs—be it e-commerce, SaaS, or IoT.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;Ready to dive in? Clone the repository and follow the setup instructions in the README to get it running locally. You’ll find detailed comments and documentation to guide you through the codebase. Play around with the GraphQL playground, tweak the gRPC services, or extend the repository pattern to fit your use case.&lt;/p&gt;

&lt;p&gt;Here’s the link again: &lt;a href="https://github.com/tpmabdulkareem/NestJS-Microservice-Backend-with-Repository-Pattern-Prisma-GraphQL-gRPC" rel="noopener noreferrer"&gt;NestJS Microservice Backend&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  What’s Next?
&lt;/h3&gt;

&lt;p&gt;This is just the beginning! I’m planning to add features like authentication, event-driven messaging with Kafka or RabbitMQ, and CI/CD pipelines to make this even more production-ready. Have ideas or suggestions? Feel free to open an issue or submit a PR—I’d love to collaborate!&lt;/p&gt;

&lt;p&gt;Building scalable backends doesn’t have to be daunting. With the right tools and patterns, you can create systems that are both powerful and adaptable. I hope this project inspires you to explore the possibilities of NestJS microservices and take your backend development to the next level.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>graphql</category>
      <category>grpc</category>
      <category>prisma</category>
    </item>
    <item>
      <title>Understanding the Next.js Middleware Bypass Vulnerability (CVE-2025-29927): A Deep Dive into CVE with CVSS 9.1</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Tue, 25 Mar 2025 09:49:14 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/understanding-the-nextjs-middleware-bypass-vulnerability-cve-2025-29927-a-deep-dive-into-cve-1ok0</link>
      <guid>https://dev.to/abdulkareemtpm/understanding-the-nextjs-middleware-bypass-vulnerability-cve-2025-29927-a-deep-dive-into-cve-1ok0</guid>
      <description>&lt;p&gt;&lt;em&gt;March 25, 2025&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Next.js, the popular React-based framework developed by Vercel, has long been a cornerstone for developers building modern, scalable web applications. Known for its robust feature set—including server-side rendering, static site generation, and a powerful middleware system—it’s trusted by enterprises like Twitch, Spotify, and OpenAI. However, a recently disclosed security vulnerability, tracked as &lt;strong&gt;CVE-2025-29927&lt;/strong&gt;, has sent shockwaves through the developer community. With a &lt;strong&gt;CVSS score of 9.1&lt;/strong&gt;, this critical flaw exposes self-hosted Next.js applications to an authorization bypass that could allow attackers to access sensitive resources with alarming ease. In this blog, we’ll take a deep dive into what CVE-2025-29927 is, how it works, its impact, and the steps you can take to protect your applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CVE-2025-29927?
&lt;/h2&gt;

&lt;p&gt;CVE-2025-29927 is an authorization bypass vulnerability affecting the middleware component of Next.js, a framework that enhances React with full-stack capabilities. Middleware in Next.js acts as a gatekeeper, intercepting HTTP requests before they reach application routes. Developers commonly use it to enforce authentication, manage access control, rewrite paths, redirect users, or apply security headers like Content Security Policy (CSP). The vulnerability, disclosed on March 21, 2025, by the Next.js team, stems from a design flaw in how Next.js processes an internal HTTP header: &lt;strong&gt;x-middleware-subrequest&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This header was originally intended to prevent infinite loops during middleware execution by tracking recursive subrequests. However, the flaw allows attackers to manipulate this header externally, tricking the framework into skipping middleware entirely. With a single, crafted HTTP request, attackers can bypass critical security checks—such as authentication or authorization—potentially gaining access to protected routes like admin panels or user dashboards.&lt;/p&gt;

&lt;p&gt;Assigned a CVSS (Common Vulnerability Scoring System) score of 9.1 out of 10, this vulnerability is classified as &lt;strong&gt;critical&lt;/strong&gt; due to its high impact, ease of exploitation, and the absence of required privileges or user interaction. The affected versions span a wide range, from &lt;strong&gt;11.1.4 to 15.2.2&lt;/strong&gt;, meaning years’ worth of Next.js deployments could be at risk if not patched.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does the Vulnerability Work?
&lt;/h2&gt;

&lt;p&gt;To understand the mechanics of CVE-2025-29927, let’s first explore the role of middleware in Next.js. Middleware runs server-side before a request reaches its final destination (e.g., a page or API endpoint). It’s a powerful tool for implementing logic like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verifying user authentication via cookies or tokens.&lt;/li&gt;
&lt;li&gt;Restricting access to specific routes based on user roles.&lt;/li&gt;
&lt;li&gt;Adding security headers to mitigate client-side attacks.&lt;/li&gt;
&lt;li&gt;Redirecting requests based on geolocation or other conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Next.js framework uses the x-middleware-subrequest header internally to manage subrequests and avoid infinite recursion—a safeguard to ensure middleware doesn’t repeatedly process the same request. The header’s value typically includes a colon-separated list (e.g., middleware:middleware:middleware), and the framework checks this against a recursion depth limit (defaulting to 5). If the limit is exceeded, middleware execution stops, and the request proceeds via NextResponse.next().&lt;/p&gt;

&lt;p&gt;Here’s where the vulnerability emerges: Next.js does not sufficiently validate the &lt;em&gt;source&lt;/em&gt; of this header. Attackers can craft an HTTP request with a manipulated x-middleware-subrequest header, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this header is present with a value that exceeds the recursion threshold—or mimics an internal subrequest—the middleware logic is bypassed entirely. The request skips authentication, authorization, or any other checks implemented in middleware, proceeding directly to the target route. For example, an attacker could access an /admin dashboard without logging in, simply by adding this header to their request.&lt;/p&gt;

&lt;p&gt;The exploit’s simplicity is what makes it so dangerous. It requires no authentication, no special privileges, and no complex attack chain—just a single HTTP header modification that can be performed with tools like curl or a web browser’s developer tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proof-of-Concept Example
&lt;/h3&gt;

&lt;p&gt;Imagine a Next.js application with middleware that restricts access to an admin dashboard:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;// middleware.js&lt;br&gt;
export function middleware(request) {&lt;br&gt;
  const isAuthenticated = request.cookies.get("auth_token");&lt;br&gt;
  if (!isAuthenticated) {&lt;br&gt;
    return Response.redirect("/login");&lt;br&gt;
  }&lt;br&gt;
  return NextResponse.next();&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Normally, unauthenticated users would be redirected to /login. However, an attacker could send:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -H "x-middleware-subrequest: middleware:middleware:middleware:middleware:middleware" http://example.com/admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This request bypasses the middleware check, granting direct access to /admin without an auth_token. The implications are severe, especially for applications relying solely on middleware for security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impact and Scope
&lt;/h2&gt;

&lt;p&gt;The impact of CVE-2025-29927 is magnified by Next.js’s widespread adoption. With nearly 10 million weekly downloads and over 330,000 internet-facing instances (according to Shodan), the framework powers applications across industries, including finance, healthcare, and Web3. The vulnerability’s reach is further compounded by its broad version coverage—any self-hosted Next.js application running versions 11.1.4 through 15.2.2 with middleware-based security controls is potentially vulnerable.&lt;/p&gt;

&lt;p&gt;Key risks include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Authentication Bypass&lt;/strong&gt;: Attackers can access protected routes (e.g., admin panels, user dashboards) without credentials, exposing sensitive data or functionality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Security Policy (CSP) Bypass&lt;/strong&gt;: If middleware sets CSP headers to prevent cross-site scripting (XSS), bypassing it could enable client-side attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Geographic or Session-Based Restriction Evasion&lt;/strong&gt;: Middleware enforcing location-based or session-based rules can be circumvented, allowing unauthorized access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Poisoning&lt;/strong&gt;: Bypassing cache-control middleware could let attackers poison caches with malicious content.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notably, the vulnerability only affects &lt;strong&gt;self-hosted Next.js applications&lt;/strong&gt; using next start with output: "standalone". Applications hosted on Vercel or Netlify, or those deployed as static exports, are not impacted, as these platforms either automatically patched the issue or don’t rely on middleware in the same way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Discovered It?
&lt;/h2&gt;

&lt;p&gt;The vulnerability was discovered by security researcher &lt;strong&gt;Rachid Allam (zhero)&lt;/strong&gt;, with additional analysis from &lt;strong&gt;Yasser Allam&lt;/strong&gt;. Reported privately to the Next.js team via GitHub’s vulnerability reporting system on February 27, 2025, the issue was triaged by March 14, with patches released shortly after. Rachid’s technical write-up, published post-disclosure, provided a detailed breakdown of the exploit, accelerating awareness—and unfortunately, the need for immediate action as exploit details became public.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mitigation and Fixes
&lt;/h2&gt;

&lt;p&gt;The Next.js team responded swiftly, releasing patched versions to address CVE-2025-29927. The fixed versions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;15.2.3&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;14.2.25&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;13.5.9&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;12.3.5&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For users on older versions (11.1.4 through 13.5.6), upgrading to a patched version is strongly recommended, though backported fixes may not cover all cases. The patch modifies how Next.js handles the x-middleware-subrequest header, ensuring it cannot be externally manipulated to bypass middleware.&lt;/p&gt;

&lt;h3&gt;
  
  
  Immediate Workaround
&lt;/h3&gt;

&lt;p&gt;If upgrading isn’t immediately feasible, a temporary mitigation is to block or strip the x-middleware-subrequest header at the edge or proxy level (e.g., via a load balancer, reverse proxy, or WAF). This must be done &lt;em&gt;outside&lt;/em&gt; the Next.js application, as middleware itself can’t reliably filter the header due to the bypass mechanism. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NGINX Configuration&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;location / {
    proxy_set_header x-middleware-subrequest "";
    proxy_pass http://nextjs_app;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apache Configuration&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RequestHeader unset x-middleware-subrequest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare WAF&lt;/strong&gt;: Add a managed rule to block requests containing the header (available as an opt-in rule since March 22, 2025).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While effective, this workaround may disrupt legitimate subrequest functionality in some setups, so testing is critical.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long-Term Best Practices
&lt;/h3&gt;

&lt;p&gt;Beyond patching, this vulnerability underscores broader security lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Defense in Depth&lt;/strong&gt;: Don’t rely solely on middleware for security. Implement additional checks at the route or API level.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input Validation&lt;/strong&gt;: Treat all user-controlled inputs, including HTTP headers, as untrusted and validate them rigorously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring&lt;/strong&gt;: Use tools like Shodan or SOCRadar’s Attack Surface Management to identify exposed Next.js instances in your environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why CVSS 9.1?
&lt;/h2&gt;

&lt;p&gt;The CVSS score of 9.1 reflects the vulnerability’s severity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Attack Vector: Network&lt;/strong&gt; – Exploitable remotely over the internet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attack Complexity: Low&lt;/strong&gt; – Requires minimal effort (just a header modification).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privileges Required: None&lt;/strong&gt; – No authentication needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Interaction: None&lt;/strong&gt; – No victim action required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidentiality/Integrity Impact: High&lt;/strong&gt; – Potential for significant data exposure or modification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Availability Impact: None&lt;/strong&gt; – No direct denial-of-service effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This combination makes CVE-2025-29927 a high-priority issue demanding immediate attention.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;CVE-2025-29927 serves as a stark reminder that even widely trusted frameworks can harbor critical flaws. Its ease of exploitation—requiring only a single HTTP header—and its potential to compromise authentication, authorization, and security controls make it a pressing concern for Next.js users. If you’re running a self-hosted Next.js application, check your version and upgrade to a patched release (15.2.3, 14.2.25, 13.5.9, or 12.3.5) immediately. For those unable to patch, implement the header-blocking workaround and plan a swift update.&lt;/p&gt;

&lt;p&gt;As the Next.js team continues to refine its security processes—acknowledging communication missteps with partners during this disclosure—developers must stay vigilant. Regularly audit your dependencies, simulate attacks with tools like the Picus Security Validation Platform, and adopt a multi-layered security approach to safeguard your applications. In an era of escalating cyber threats, proactive defense is no longer optional—it’s essential.&lt;/p&gt;

&lt;p&gt;Stay secure, and happy coding!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>vulnerablity</category>
      <category>middleware</category>
      <category>security</category>
    </item>
    <item>
      <title>Harnessing the Power of AstroJS: Building High-Performance, Framework-Agnostic Web Apps</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Tue, 06 Feb 2024 05:58:54 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/harnessing-the-power-of-astrojs-building-high-performance-framework-agnostic-web-apps-3cc4</link>
      <guid>https://dev.to/abdulkareemtpm/harnessing-the-power-of-astrojs-building-high-performance-framework-agnostic-web-apps-3cc4</guid>
      <description>&lt;p&gt;In today's dynamic web landscape, developers seek out powerful tools that deliver speed, flexibility, and exceptional user experiences. AstroJS is emerging as a game-changer, enabling you to leverage familiar frameworks like Svelte, React, and Vue within a static site generator (SSG) architecture. This guide delves into building a web app using this innovative approach, empowering you to create:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blazing-fast performance:&lt;/strong&gt; AstroJS serves pre-rendered HTML by default, ensuring lightning-quick initial page loads and improved SEO.&lt;br&gt;
&lt;strong&gt;Framework flexibility:&lt;/strong&gt; Embrace the freedom to choose the right tool for the job, seamlessly integrating Svelte, React, or Vue components based on your needs.&lt;br&gt;
&lt;strong&gt;Tailwind CSS elegance:&lt;/strong&gt; Style your app effortlessly with Tailwind's utility-first approach, minimizing CSS overhead and boosting developer productivity.&lt;br&gt;
&lt;strong&gt;Robust TypeScript typing:&lt;/strong&gt; Enforce code stability and maintainability with TypeScript's type checking, catching errors early and enhancing code collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Scaffolding:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Project Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the Astro CLI to initialize your project: 
&lt;code&gt;npx create-astro my-app --template vue --use-typescript&lt;/code&gt; (or substitute Vue with your preferred framework).&lt;/li&gt;
&lt;li&gt;Install &lt;em&gt;tailwindcss&lt;/em&gt; and its dependencies according to the official documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Tailwind Integration:&lt;/strong&gt;&lt;br&gt;
Configure Tailwind in astro.config.mjs by following the @astrojs/tailwind plugin's instructions.&lt;br&gt;
Create a tailwind.config.js file in your project root to customize classes and purge unused styles.&lt;/p&gt;

</description>
      <category>astro</category>
      <category>react</category>
      <category>svelte</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Next.js 13: New Features and Updates</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Mon, 01 May 2023 04:12:31 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/nextjs-13-new-features-and-updates-10c</link>
      <guid>https://dev.to/abdulkareemtpm/nextjs-13-new-features-and-updates-10c</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv913f4g9e9i2cdk8g5tr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv913f4g9e9i2cdk8g5tr.png" alt="Image description" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next.js, the popular React framework, has recently released its latest stable version, Next.js 13. This version comes with several new features and updates that aim to improve the developer experience and performance of building web applications. Let's take a closer look at some of the major changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  App Directory (Beta)
&lt;/h2&gt;

&lt;p&gt;One of the most significant changes introduced in Next.js 13 is the new App Directory feature. This feature enables developers to bundle all their custom components, pages, and APIs in a single directory, which helps to declutter the project structure and increases productivity. It also includes a new app/ layout, where developers can define global components or features like custom error pages or a wrapper for authentication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswc0r7p5nxcr3nkksz4u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fswc0r7p5nxcr3nkksz4u.png" alt="Image description" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Updated Routing and Layouts
&lt;/h2&gt;

&lt;p&gt;Next.js 13 also features improved routing and layouts capabilities, which align with the future of React. The App Router has been updated, which allows developers to define layouts with dynamic content, nested routes, and parameterized paths. Developers can easily share global components and functions between layouts, which reduces code duplication and improves code quality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcoo78h0m3r550vt1jw8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcoo78h0m3r550vt1jw8y.png" alt="Image description" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Turbopack Updates
&lt;/h2&gt;

&lt;p&gt;Another significant update in Next.js 13 is the support for the TurboPack Optimization feature, which speeds up the application's loading time. TurboPack optimizes the JavaScript code by analyzing the application at the module-level and creating smaller, more efficient bundles. Additionally, Next.js 13 supports the latest version of popular front-end Frameworks, like Tailwind CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlwzxpkftnhvjuaagznf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzlwzxpkftnhvjuaagznf.png" alt="Image description" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  API Routes Enhancements
&lt;/h2&gt;

&lt;p&gt;The new version of Next.js provides a more modern version of API Routes , which makes it easier for developers to create serverless functions with server-side rendering capabilities. This new feature deeply integrates with the routing system, allowing developers to define API Routes alongside pages and layouts. The modern API Routes provide an intuitive request handler pattern with native support for request monitoring, rate-limiting, and middleware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Updates
&lt;/h2&gt;

&lt;p&gt;Next.js 13 also includes various other updates, like Font Optimization, updated Image, Link, and Script components, enhanced Next.js analytics with real-time metrics, and improved TypeScript support.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>ssr</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Getting Started with React Testing Library</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Tue, 04 Apr 2023 11:41:51 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/getting-started-with-react-testing-library-nl7</link>
      <guid>https://dev.to/abdulkareemtpm/getting-started-with-react-testing-library-nl7</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpyojhmwq3e1e7gurwwrr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpyojhmwq3e1e7gurwwrr.jpg" alt="coverimage" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Testing Library is a popular testing utility that helps developers test their React applications more effectively. It allows developers to write tests that simulate real user interactions and ensure that their applications behave as expected. In this article, we'll walk through the basics of React Testing Library and learn how to write tests for React components using this library.&lt;/p&gt;

&lt;p&gt;Before we start, make sure that you have a basic understanding of React and its ecosystem. You should also have some experience with writing tests using a testing framework like Jest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing React Testing Library:&lt;/strong&gt;&lt;br&gt;
To install React Testing Library, you can use npm or yarn. Simply run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @testing-library/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @testing-library/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Writing Your First Test:&lt;/strong&gt;&lt;br&gt;
Let's start by writing a simple test for a React component. Suppose we have a component called Greeting that takes a name prop and displays a greeting message. Here's what the component looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';

function Greeting(props) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Hello, {props.name}!&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Greeting;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this component, create a new file called Greeting.test.js and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import { render } from '@testing-library/react';
import Greeting from './Greeting';

test('renders greeting message', () =&amp;gt; {
  const { getByText } = render(&amp;lt;Greeting name="John" /&amp;gt;);
  const greetingElement = getByText(/Hello, John!/i);
  expect(greetingElement).toBeInTheDocument();
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down this code:&lt;/p&gt;

&lt;p&gt;We import the render function from @testing-library/react and the Greeting component from ./Greeting.&lt;br&gt;
We define a new test case using the test function provided by Jest. This test case checks whether the component renders a greeting message with the correct name.&lt;br&gt;
We use the render function to render the Greeting component with the name prop set to "John". The render function returns an object with various query functions that we can use to find elements in the rendered component.&lt;br&gt;
We use the getByText query function to find an element that contains the text "Hello, John!". The getByText function searches for an element that matches the given text, ignoring case.&lt;br&gt;
We use the toBeInTheDocument matcher provided by Jest to check whether the greetingElement is present in the document.&lt;br&gt;
When you run this test using Jest, it should pass.&lt;/p&gt;

&lt;p&gt;Simulating User Interactions:&lt;br&gt;
One of the key features of React Testing Library is its ability to simulate user interactions. Let's say we have another component called Counter that displays a counter value and two buttons to increment and decrement the value. Here's what the component looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const handleIncrement = () =&amp;gt; {
    setCount(count + 1);
  };

  const handleDecrement = () =&amp;gt; {
    setCount(count - 1);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Count: {count}&amp;lt;/h1&amp;gt;
      &amp;lt;button onClick={handleIncrement}&amp;gt;+&amp;lt;/button&amp;gt;
      &amp;lt;button onClick={handleDecrement}&amp;gt;-&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default Counter;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this component, we can use React Testing Library to simulate user clicks on the buttons and verify that the counter value updates correctly.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>unittesing</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Push Notification | React Native | Android</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Wed, 08 Apr 2020 12:31:28 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/push-notification-react-native-android-5n6</link>
      <guid>https://dev.to/abdulkareemtpm/push-notification-react-native-android-5n6</guid>
      <description>&lt;p&gt;In React Native, most of the developers use third-party services like Firebase or OneSignal for Push Notification service. Here through this tutorial, I wish to show you how we can do Push Notification without these third-party services.&lt;/p&gt;

&lt;p&gt;We can do this by &lt;a href="//npmjs.com/package/react-native-push-notification"&gt;React Native Push Notifications&lt;/a&gt; library.we can create both local push notifications and scheduled ones too. This would be similar to having set an event in the app or even a timer to trigger a notification while running the app, or even after it has been closed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.dribbble.com%2Fusers%2F310943%2Fscreenshots%2F2518631%2Fpush-notifications-illustration2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.dribbble.com%2Fusers%2F310943%2Fscreenshots%2F2518631%2Fpush-notifications-illustration2.gif" title="Push Notification" alt="Gif" width="1024" height="1024"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Open your project folder in your favourite editor. Install &lt;code&gt;react-native-push-notification&lt;/code&gt; package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save react-native-push-notification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Setting up Android Files
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;android/build.gradle&lt;/code&gt; and add the following changes:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ext {
        googlePlayServicesVersion = "+"
        firebaseVersion = "+"
        ...
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After that, open &lt;code&gt;AndroidManifest.xml&lt;/code&gt; and add following changes:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
&amp;lt;uses-permission android:name="android.permission.WAKE_LOCK" /&amp;gt;
    &amp;lt;permission
        android:name="${applicationId}.permission.C2D_MESSAGE"
        android:protectionLevel="signature" /&amp;gt;
    &amp;lt;uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" /&amp;gt; 
    &amp;lt;uses-permission android:name="android.permission.VIBRATE" /&amp;gt;
    &amp;lt;uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/&amp;gt;

&amp;lt;application ....&amp;gt;
        &amp;lt;meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
                android:value="YOUR NOTIFICATION CHANNEL NAME"/&amp;gt;
        &amp;lt;meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
                    android:value="YOUR NOTIFICATION CHANNEL DESCRIPTION"/&amp;gt;
        &amp;lt;meta-data  android:name="com.dieam.reactnativepushnotification.notification_color"
                    android:resource="@android:color/white"/&amp;gt;
        &amp;lt;receiver
            android:name="com.google.android.gms.gcm.GcmReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND" &amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name="com.google.android.c2dm.intent.RECEIVE" /&amp;gt;
                &amp;lt;category android:name="${applicationId}" /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;
        &amp;lt;/receiver&amp;gt;
        &amp;lt;receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" /&amp;gt;
        &amp;lt;receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver"&amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name="android.intent.action.BOOT_COMPLETED" /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;
        &amp;lt;/receiver&amp;gt;
        &amp;lt;service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationRegistrationService"/&amp;gt;
        &amp;lt;service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerServiceGcm"
            android:exported="false" &amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name="com.google.android.c2dm.intent.RECEIVE" /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;
        &amp;lt;/service&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After that, In &lt;code&gt;android/settings.gradle&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;include ':react-native-push-notification'
project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/android')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And finally, create the file &lt;code&gt;android/app/src/res/values/colors.xml&lt;/code&gt; and add the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;resources&amp;gt;
    &amp;lt;color name="white"&amp;gt;#FFF&amp;lt;/color&amp;gt;
&amp;lt;/resources&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it for the Android Setup!&lt;/p&gt;
&lt;h3&gt;
  
  
  Putting it all together!
&lt;/h3&gt;

&lt;p&gt;Open your &lt;code&gt;App.js&lt;/code&gt; and add the following&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import PushNotification from 'react-native-push-notification';

...

//Push Notification configuration 
    PushNotification.configure({
      onRegister: function (token) {
        console.log('TOKEN:', token);
      },
      onNotification: function (notification) {
        console.log('NOTIFICATION:', notification);
        notification.finish(PushNotificationIOS.FetchResult.NoData);
      },
      permissions: {
        alert: true,
        badge: true,
        sound: true,
      },
      popInitialNotification: true,
      requestPermissions: true,
    });

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For Local Notifications,&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Function for Local Notification
  const localPushNotification = () =&amp;gt; {
    PushNotification.localNotification({
      title: 'Local Notification',
      message: 'This is a local notification example',
    });
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://d3ep2kbadr6005.cloudfront.net/krmblog/Local%20Notifications.gif" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For Scheduled Notifications,&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Function For Scheduled Notification
  const scheduledNotification = () =&amp;gt; {
    PushNotification.localNotificationSchedule({
      title: 'Scheduled Notification',
      message: 'Scheduled Notification Message', // (required)
      date: new Date(Date.now() + 60 * 300),
    });
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://d3ep2kbadr6005.cloudfront.net/krmblog/Scheduled%20Notifications.gif" rel="noopener noreferrer"&gt;Preview&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Wrap up
&lt;/h3&gt;

&lt;p&gt;If everything was successful you should be able to schedule local notifications! Here the complete repo for the project: &lt;/p&gt;

&lt;p&gt;&lt;a href="image.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg0nj1s8ud77udhgqtfq.png" width="800" height="1422"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/tpmabdulkareem" rel="noopener noreferrer"&gt;
        tpmabdulkareem
      &lt;/a&gt; / &lt;a href="https://github.com/tpmabdulkareem/Push-Notification-App" rel="noopener noreferrer"&gt;
        Push-Notification-App
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A simple example for react native push notification
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/zo0r/react-native-push-notification#readme" rel="noopener noreferrer"&gt;https://github.com/zo0r/react-native-push-notification#readme&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Generate your own React Component using CLI by using Plop.js</title>
      <dc:creator>ABDULKAREEM</dc:creator>
      <pubDate>Tue, 07 Apr 2020 11:28:58 +0000</pubDate>
      <link>https://dev.to/abdulkareemtpm/generate-your-own-react-component-using-cli-by-using-plop-js-2ei</link>
      <guid>https://dev.to/abdulkareemtpm/generate-your-own-react-component-using-cli-by-using-plop-js-2ei</guid>
      <description>&lt;p&gt;Those who have previously worked in Angular may be noticed that the React ecosystem is not standardized as an Angular ecosystem. A new React app has nothing much. The directory and dependencies structures can be made as our own wish. That could be good, but that rise lack of uniformity amongst React developers.&lt;/p&gt;

&lt;p&gt;We don't have a CLI command similar to &lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;angular-cli&lt;/a&gt; to generate a new component, the research to overcome this helped me to find &lt;a href="https://plopjs.com/documentation/#getting-started" rel="noopener noreferrer"&gt;plop.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Plop?&lt;/strong&gt;&lt;br&gt;
Micro-generator framework that makes it easy for an entire team to create files with a level of uniformity.&lt;/p&gt;

&lt;p&gt;Let's Start coding...&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up your app
&lt;/h3&gt;

&lt;p&gt;First, let’s create a new react app using &lt;a href="https://reactjs.org/docs/create-a-new-react-app.html#create-react-app" rel="noopener noreferrer"&gt;create-react-app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app my-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once the app is successfully created, now change your working directory by running below command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd my-app&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Installing plop.js
&lt;/h3&gt;

&lt;p&gt;Install plop as a dev-dependency&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save-dev plop&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up the project structure
&lt;/h3&gt;

&lt;p&gt;We need to decide, what boilerplate you want to generate. Over the last few projects, I'm using the following structure for my React app.&lt;/p&gt;
&lt;h3&gt;
  
  
  Configuring plop
&lt;/h3&gt;

&lt;p&gt;create a &lt;code&gt;plopfile.js&lt;/code&gt; in your root app folder and add the below code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readdirSync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getDirectories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;withFileTypes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isDirectory&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dirent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;directories&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getDirectories&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/pages&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Create a component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// User input prompts provided as arguments to the template&lt;/span&gt;
        &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Raw text input&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Variable name for this input&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Prompt to display on command line&lt;/span&gt;
                &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What is your component name?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Raw text input&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confirm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Variable name for this input&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;isCommon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Prompt to display on command line&lt;/span&gt;
                &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Is it common component?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCommon&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="c1"&gt;// Raw text input&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Variable name for this input&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Prompt to display on command line&lt;/span&gt;
                &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Choose container?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;directories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCommon&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/common/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/pages/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isCommon&lt;/span&gt;
                &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="c1"&gt;// Add a new file&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="c1"&gt;// Path for the new file&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/{{pascalCase name}}.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="c1"&gt;// Handlebars template used to generate content of new file&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/Component.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/index.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/{{pascalCase name}}.styled.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/styled.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/{{pascalCase name}}.stories.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/stories.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                  &lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="c1"&gt;// Add a new file&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="c1"&gt;// Path for the new file&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/{{pascalCase name}}.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="c1"&gt;// Handlebars template used to generate content of new file&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/Component.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/index.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{pascalCase name}}/{{pascalCase name}}.styled.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/styled.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="p"&gt;},&lt;/span&gt;
                  &lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Create a page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;// User input prompts provided as arguments to the template&lt;/span&gt;
        &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Raw text input&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Variable name for this input&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Prompt to display on command line&lt;/span&gt;
                &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What is your page name?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Add a new file&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Path for the new file&lt;/span&gt;
                &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/pages/{{pascalCase name}}/{{pascalCase name}}.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// Handlebars template used to generate content of new file&lt;/span&gt;
                &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/Component.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/pages/{{pascalCase name}}/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/index.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/pages/{{pascalCase name}}/{{pascalCase name}}.styled.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plop-templates/Component/styled.js.hbs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating plop-templates
&lt;/h3&gt;

&lt;p&gt;We need to create a plop-templates so that plop.js generates the new components based on that template.&lt;/p&gt;

&lt;p&gt;Inside your root app folder create a new folder called plop-templates and create templates with &lt;code&gt;.hbs&lt;/code&gt; extension indicates that this is a &lt;a href="https://handlebarsjs.com/" rel="noopener noreferrer"&gt;Handlebars.js&lt;/a&gt; template.&lt;/p&gt;

&lt;p&gt;For my folder structure, I have four template files as follows:&lt;/p&gt;

&lt;h5&gt;
  
  
  1. Functional component
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fcomponent.hbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fcomponent.hbs.png" title="Functional Component" alt="Functional Component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  2. Styled Component
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fstyled.hbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fstyled.hbs.png" title="Functional Component" alt="Functional Component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  3. Storybook
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fstories.hbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fstories.hbs.png" title="Functional Component" alt="Functional Component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  4. index.js
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Findex.hbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Findex.hbs.png" title="Functional Component" alt="Functional Component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding script to package.json
&lt;/h3&gt;

&lt;p&gt;And lastly, we’ll want to add a script to our &lt;code&gt;package.json&lt;/code&gt; to create an alias for the plop command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"plop"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, our plop setup is complete now open your terminal and run &lt;code&gt;npm run generate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fgenerate.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fgenerate.png" title="npm run generate" alt="npm run generate" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It prompts a question with two options &lt;code&gt;component&lt;/code&gt; or &lt;code&gt;page&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you choose &lt;code&gt;component&lt;/code&gt;. Then,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2FmyComponent%2520yes.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2FmyComponent%2520yes.png" title="npm run generate | component" alt="npm run generate | component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After entering the component name and hitting enter key, it will prompt another question asking whether it is a common component or not. If you choose common, then the component will be generated under the common folder, else it maps the page folder, from where you could generate the component inside the respective page component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fcomponent%2520generation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2Fcomponent%2520generation.png" title="generated component" alt="generated component" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you were chosen &lt;code&gt;page&lt;/code&gt; instead of &lt;code&gt;component&lt;/code&gt;, then the resulting will be:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2FPage.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd3ep2kbadr6005.cloudfront.net%2Fkrmblog%2FPage.png" title="generated page component" alt="generated pagecomponent" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we’ve built out our component generator, we can build generators for Redux, Hooks, and services as well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Thanks 🙌 for reading and happy coding!&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>react</category>
      <category>npm</category>
      <category>reactnative</category>
    </item>
  </channel>
</rss>
