Editor’s note: This blog was most recently updated on July 16, 2026, to improve the reader experience with new cross-links to related authentication and UX design resources, plus a curated list of recommended reading for deeper exploration. It was previously rewritten in 2025 by Allie Paschal to provide three real-world examples of great login screens, expand on best practices, and cover FAQs.

Oftentimes, login screens feel like an afterthought in UX design — they’re typically not a key part of the user experience and fill more of a functional requirement. However, the login process is a critical touchpoint in your user’s journey as it serves as the place where they enter the product.

Although you might not notice login screens with good design (since you experience no friction), I bet you remember the ones with a poor design. If a user doesn’t feel like their account is well-secured or can’t remember their password, they might get frustrated and abandon the login process altogether. And if fewer and fewer users are logging in to the website or app, you may not have the website or app much longer.

Google Desktop Login
Google’s desktop web login page

Users create their first impression with a product through the login process. This first interaction should guide the user to access their account or create a new one. It should also visually reflect the brand’s identity and be simple and intuitive, but also give helpful instructions when needed.

There’s so much more to designing for login screens than you might initially think. But whether you’re designing a new login screen from scratch or refining your current design, these examples and tips will help optimize your designs for an engaging and positive login process.

Examples of login screen designs

To understand what makes a good login screen, pay attention to what these successful products do.

Adobe Creative Cloud

Adobe Creative Cloud holds the collection of Adobe apps, including Photoshop, Illustrator, and InDesign. It has both a website and a desktop app login:

Abode Desktop Login
Adobe Creative Cloud’s desktop app login page

Adobe Creative Cloud’s login page is minimal, yet it includes Adobe’s brand identity of creativity and innovation. The sign-in form has a total of eight buttons and one text field, grouped in a way for a user to quickly understand they have multiple login options to choose from.

If I enter my email in the text field, then select “Continue,” I’m taken to the next screen to enter my password or to continue with Google. Here, Adobe still gives you multiple options to proceed with logging in — whether it be through the standard password, social media, or getting help:

Adobe Login After Continue
Login screen after selecting “Continue” from the initial view in Adobe

What does Adobe’s login screen do well?

  • Flexibility — Users have multiple ways to access their account (enter their email to move on to the next step, use social media channels like Google, or get help) to accommodate to different user preferences
  • Balance — Adobe prioritizes both the brand and simplicity for the login screen; the sign-in form is on an all-white card, but the background image shows interesting artwork
  • Bold call-to-action — Although the sign-in form has eight buttons, only one is a “primary button,” which is given visual styling to make it look like the most important element
  • Assistance — Adobe offers a clear button for help at the bottom of the form that says “Get help signing in” if users aren’t able to access their account from the options given

SoFi

SoFi is a personal financial company that offers services like investments, personal loans, and savings accounts. Since it’s a banking service with people’s hard-earned money on the line, the login process must be easy to use, but also have added layers of security. Similar to Adobe, SoFi has login processes for both the desktop website and native mobile application:

SoFi Desktop Login
SoFi’s desktop website login page

SoFi’s login screen is simple, straightforward, and accommodates multiple types of users, such as existing users, first-time users, or users who forgot their password. The login form is on an all-white card with two text fields and three buttons. Other than the SoFi logo and the website’s footer, the login form is the only other element on the screen.

When you select the “Log in” button after inputting your login credentials with your email and password, you’re presented with a two-factor authentication screen where you must input a code your mobile phone received via SMS. This gives you a sense of security that your accounts are safe, but you can also select the “Remember this device” checkbox on the two-factor page if you don’t want to authenticate each time you access your account on a certain device.

SoFi Two Factor
SoFi’s two-factor authentication login screen

What does SoFi’s login screen do well?

  • Supports different users — Both new and existing users with different intentions will access this login screen; new users can use the “Sign up” button below the form, while existing users can fill in the input fields and select the “Log in” button
  • Security measures — Although this adds an additional step when logging in, SoFi’s two-factor authentication adds greater protection to your account, which helps users trust that their accounts are safe with SoFi
  • Logical sequence — This login form arranges the input fields in an intuitive way for users to go through the flow of logging in — they enter their email and password, then select the “Log in” button to authenticate the device

Spotify

Spotify is a music streaming service that provides access to millions of songs, artists, and podcasts. Spotify’s user interface and branding have received a lot of praise, but have you observed if their login screens follow suit?

Spotify Native Login
Spotify’s native mobile app login screens

Since these login screens are for a mobile device, Spotify takes a step-by-step approach compared to Adobe and SoFi. The first screen only has two buttons that display “Sign up free” or “Log in.” After pressing “Log in,” you’re given four methods to log in as well as the choice to “Sign up.” After pressing “Continue with email,” you’re taken to a new page to enter your email and password.

If you fail to log in with the correct password, Spotify proactively displays a bottom sheet letting you know they sent help to your email.

What do Spotify’s login screens do well?

  • Divides the process — Instead of including all possible paths the user can take on the initial screen, Spotify chunks it into different steps so the user isn’t overwhelmed by too many options on a mobile device
  • Clear call-to-action — Each screen shows a distinct green button with its primary call-to-action, such as “Sign up free” and “Continue with email,” to guide the user through the login process
  • Proactive help — When Spotify detects that you’ve tried to log in a few times without success, it sends help without the user having to ask for it (e.g., sending a link to log in versus the user selecting a “Forgot password?” button)
  • Balance — Similar to Adobe, the login screens balance both simplicity and Spotify’s branding with negative space and its recognizable neon-green color

UX principles behind good login screens

Now that you’ve explored examples of effective login designs, keep the following UX principles in mind to build a good login screen:

  • Consistent and recognizable — Think about how many times a typical user logs into products on a daily basis. If each product has a different login experience, the user’s cognitive load increases from needing to learn a new process each time. Instead, login screens use the same design patterns (like using the same UI components) so users can quickly understand and navigate the login screen
  • Simple and clear — Login screens need to be minimal and free from distractions, such as excessive branding or advertisements. The login screen should only have essential elements, like input fields with explicit labels and ways to get help
  • Feedback and error prevention — When users are trying to log in to a product, the design should work in every way possible to help the user complete the task. This includes giving meaningful feedback when the user succeeds or fails, as well as preventing errors from happening in the first place
  • User control and flexibility — Unless your product has strict security measures for access to sensitive data or finances, you should give users multiple ways to log into the product. When users can log in through a standard password, Google, or Face ID, the barriers to accessing the product decrease
  • Accessible and inclusive — Users of different abilities need to be able to log in to the product; you don’t want to exclude a user group from experiencing a product because they can’t operate the login screen. Accessibility issues can be minimized by paying attention to color contrast ratios for text and UI components, keyboard functionality with focusable elements, and providing multiple ways to log in (similar to user control and flexibility)

FAQs about login screens

This section walks you through the most frequently asked questions about login screens.

What makes a “good” login screen?

Even though the examples of login screens looked different, they have multiple similarities that make each of them effective.

These include:

  • Simple and minimal — On each of the login screens, the login form and its UI components are the only things on the page, eliminating distraction and clutter to reduce the user’s cognitive load
  • Usable yet secure — Users need to be able to gain easy access to their account with any product while keeping their information secure; providing multiple, safe options for users to log in with maintains this balance
  • Error prevention: It’s best to notify users before they make a mistake, such as warnings for caps lock or including constraints on input fields; this helps users proactively address errors before they occur

Creating a “good” login screen from scratch is challenging – Figma offers login page templates for desktop and mobile screens to give you a jump-start.

Apple Login Screen
Apple’s MacOS provides a “caps lock” symbol on the password field to prevent errors

How do I reduce login friction while maintaining security?

Providing an easy way to log in with strong security is a delicate balance — the goal is to minimize the user’s effort while making the authentication robust so people can’t access an account that’s not theirs.

Methods to balance login friction and security include:

  • Provide multiple login methods — Provide alternative login methods like social logins (Google), but you can also use password-less methods (one-time passcodes) and biometric authentication (Face ID)
  • Enhance password usability — If users prefer to use a traditional password over alternative login methods, ensure the password input field supports auto-fill, includes a “show password” toggle, and includes real-time validation (checks password length)
  • Simplify two-factor authentication — Some industries, like finance and healthcare, require two-factor authentication due to data privacy; streamline this process by providing the user push notifications over manual codes, and allow the user to trust their device

Should I include a “show password” toggle?

Yes, include a toggle to show and hide the password because it allows users to confirm their password before submission and improves accessibility for users who rely on screen readers (screen readers may ignore masked characters).

Best practices for including a password toggle include:

  • Hide the password by default, so the user must turn the toggle on
  • Maintain consistency with other password toggles by using the standard “eye” icon
  • Position the toggle near the password field so users understand what the toggle controls
Show And Hide Password
A toggle to show and hide the password reduces user error

What are the best practices for error handling and prevention?

Preventing errors and providing beneficial feedback when errors occur are critical aspects to consider when designing a login screen. Error prevention proactively reduces common barriers to entry, like wrong user ID or password.

Best practices to consider for error handling and prevention include:

  • Use real-time validation to highlight incorrect email formats or weak passwords
  • Allow the user to copy and paste or autofill their password
  • Don’t erase the user’s data when errors occur upon submission
  • Use clear, simple language to describe an error
  • Provide easy access to password or account recovery options

How can I make the login process accessible?

Accessibility is becoming a greater need for digital products. If a user can’t log in due to poor accessibility, they’re excluded from the entire product.

Some considerations for including accessibility for login screens include:

  • Ensure the login screen is keyboard-accessible (users can tab and interact with all fields correctly)
  • Use <label> elements to properly mark form fields and avoid using placeholder text instead of a label
  • Provide security alternatives to CAPTCHA (these can hinder users with visual or cognitive disabilities)
  • Use clear language for input fields and buttons (use “Log in” versus “Submit”)
  • Ensure high color contrast between text and its direct background

To learn more about making your login process compliant with the Web Content Accessibility Guidelines (WCAG), check out this video from GOV.UK on accessible authentication.

CAPTCHA
Example of a CAPTCHA security check

Conclusion

I get it – login screens feel like a mundane requirement the UX designers must include. The login process isn’t one of the key user flows you worked tirelessly on, and some users don’t really notice it. But it’s a more significant touchpoint than it seems; it’s the first step of the user’s journey and where they create their first impression of a product.

Creating a successful login screen is challenging. It involves balancing the company’s brand with simplicity, as well as usability with security. Not only that, you must account for the different types of users who may be accessing the login, such as new and existing users.

As a designer, you can generate this balance and user accommodation by using UX principles such as consistency, clarity, and accessibility. With these principles, you’ll design login screens that align with your users’ mental model, improve usability, and support many user groups – so users can access and start using your product.

Related reading:

  • Essential GUI design principles: Learn the core interface design principles that help create intuitive, user-friendly login experiences.
  • Multi-factor authentication design: Security meets usability in UI/UX design: Discover how to reduce authentication friction while maintaining strong account security.
  • Jakob’s Law: Creating user-centric interfaces: See why familiar interaction patterns make login flows easier for users to understand and navigate.
  • Writing clear error messages: UX guidelines and examples: Learn how to write actionable error messages that help users recover quickly from login issues.

The post 3 examples of great login screen designs appeared first on LogRocket Blog.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

Editor’s note: This blog was most recently updated on July 16, 2026, to improve the reader experience with new cross-links to related authentication and UX design resources, plus a curated list of recommended reading for deeper exploration. It was previously rewritten in 2025 by Allie Paschal to provide three real-world examples of great login screens, expand on best practices, and

How AI changed the way I approach design critiques

When AI made generating design concepts almost effortless, I realized the most valuable part of a critique was no longer the interface itself. It was understanding the context, tradeoffs, and judgment behind the final design. Here’s how AI has changed the way I run design critiques—and why I think that’s making them better.

Double Diamond Symbol

What is the Double Diamond design process?

The Double Diamond design process helps UX teams balance exploration with decision-making, guiding projects from problem discovery to solution delivery. Learn how each phase works, which tools to use, when the reverse Double Diamond makes sense, and why the framework remains relevant for modern product development.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

How AI changed the way I approach design critiques When AI made generating design concepts almost effortless, I realized the most valuable part of a critique was no longer the interface itself. It was understanding the context, tradeoffs, and judgment behind the final design. Here’s how AI has changed the way I run design critiques—and why I think that’s making

AI coding agents have a tendency to generate code that isn’t particularly maintainable. They often duplicate logic, create massive files, and produce overly complex functions that are difficult for humans to understand. As these issues accumulate over time, they can turn a codebase into a significant maintenance burden.

In many cases, asking an agent to refactor simply results in even more code being added. Manually cleaning up the code isn’t always a practical alternative either, as reviewing and refactoring large AI-generated codebases can be extremely time-consuming.

Enter Fallow, a TypeScript and JavaScript code analysis tool designed to help you keep your codebase healthy. Fallow identifies unused code, duplicate logic, and large, complex sections of code that are likely to become technical debt if left unchecked. It gives you a clear picture of where your codebase is becoming difficult to maintain before those problems grow into something much larger.

In this article, you’ll learn how to set up Fallow in your project, understand the reports it generates, and integrate it into your AI-assisted development workflow.

Why does clean code still matter in the age of AI?

One thing many developers believe AI will take away is the need to write clean code. The push for clean code has always been about preventing technical debt and spending less time untangling messy logic, making future changes easier and less expensive.

But what if the average developer believes they no longer need to worry about what their code looks like in the future because they see it as AI’s responsibility? That’s one way AI is changing the software industry. And to be fair, it’s a reasonable perspective. AI is becoming increasingly capable of maintaining and modifying its own code. But AI is still AI, and the results can be unpredictable.

That said, this isn’t always the reality. Most developers don’t write messy code because they lack the knowledge or don’t care about quality. More often, they’re working under tight deadlines, shifting priorities, and constant pressure to deliver. That’s understandable.

The problem comes later. When a codebase has accumulated years of technical debt and become difficult to understand, relying entirely on AI may not be enough. If that tool fails, you could find yourself hiring a team of developers to rewrite large parts of the application. That’s an expensive outcome, especially since many developers are hesitant to work with codebases that are difficult to maintain.

That’s why clean code still matters in the age of AI. Whether code is written by a human, an AI agent, or a combination of both, maintainability should remain a priority throughout a project’s lifecycle. AI can speed up development, but it shouldn’t become an excuse to neglect the long-term health of your codebase.

What is Fallow?

Fallow is a free, Rust-native codebase intelligence tool designed to analyze TypeScript and JavaScript projects. It acts as an automated code audit tool that provides factual analysis about a project’s overall code quality, structure, and execution pattern.

Unlike formatters and linters, which treat a codebase as a collection of individual files, Fallow treats it as an interconnected system. Because it is built on the Oxc parser ecosystem, it can sweep through codebases at sub-second speeds, making it significantly faster than older tools like knip or jscpd.

A major differentiator for Fallow is its native compatibility with AI agents. Because LLMs have limited context windows and cannot easily map a massive repository’s dependency graph, Fallow can serve as the source of truth for the AI.



Fallow combines several distinct auditing responsibilities into a single binary, which generates the following report in a single run:

To integrate seamlessly into modern developer workflows, it provides an MCP server and structured JSON output that contains machine-actionable action arrays, which enable AI agents to trigger automated tools, catch structural clutter, and self-correct code before it is ever committed.

Getting started with Fallow

Fallow has two intelligence layers: Static Intelligence and Runtime Intelligence.

The Static Intelligence layer is free and analyzes how your codebase is wired together. It helps you understand relationships between files, identify unused code, detect dead exports, and uncover other structural issues.

The Runtime Intelligence layer is optional and paid. It provides insights into what gets executed in production,

This article focuses only on the Static Intelligence layer because it’s free and provides everything you need to improve your codebase. Setting it up is straightforward too.

Simply run the following command in your project’s root directory:

npx fallow

Fallow doesn’t require any configuration. After you run the command above, it automatically detects your project’s setup by inspecting your package.json file and enables the appropriate plugins and presets. It supports frameworks such as Next.js, Vite, NestJS, SvelteKit, TanStack, and many others.

By default, the command generates a comprehensive report that combines dead code detection, code duplication, and code health and complexity into a single, structured output.

If you prefer, you can run each analysis separately using any of the following commands:

npx fallow dead code
npx fallow dupes
npx fallow health

You can also install Fallow as a development dependency if you want everyone who works on the repository to have access to it.

npm install --save-dev fallow

How do you read Fallow’s output?

The first time you run Fallow, the output can feel overwhelming because of the amount of information it provides. In this section, we’ll run Fallow against a vibe-coded application and walk through each part of the report so you can understand what it means and how to act on it.

As mentioned earlier, Fallow‘s report is divided into three main sections: Dead Code, Duplication, and Health.

How does Fallow detect dead code?

This section highlights code that isn’t structurally connected to anything else in the project, including unused files, exports, dependencies, types, and more.

As shown in the image above, each category is grouped into its own subsection under the Dead Code report.

Each subsection contains a list of file paths and the functions, exports, or declarations that Fallow has identified as unused.

To remove them, open the listed file and locate the corresponding code. Since dead code isn’t referenced anywhere else in the codebase, it’s generally safe to remove without breaking your application.

That said, Fallow can occasionally flag entry-point code as dead because it’s referenced from outside the file rather than through the project’s internal dependency graph. It’s worth reviewing these cases before deleting anything.

If you’d rather let Fallow handle the cleanup, you can run the following command to automatically remove dead code:

fallow fix –dry-run

This command may not always produce the expected results, so it’s a good idea to review the changes before committing them.

How does Fallow detect duplicate code?

The Duplication section is one of the most valuable parts of the report because it highlights code blocks that are repeated across your codebase. The output looks like this:

Like the Dead Code section, the Duplication report is divided into individual entries. However, there are a few important differences. Fallow uses AST-equivalent token matching to detect duplicate code, grouping each set of matches into what it calls a clone group.

  • The duplicated code block
  • The line count: which shows how many lines the duplicated block contains
  • The instances: which list the files and line ranges where the duplicated code appears

Let’s use the first clone group in the report shown above as an example.

In this case, the clone group indicates that the code block within the 98 – 179 line range inside the login.tsx file has 82 lines of repeated code in the signUp.tsx file.

Fallow‘s duplication detection is also more nuanced than a simple text comparison. It supports multiple detection modes that can identify duplicated logic even when variable names, strings, or other identifiers have been renamed. You can learn more about these modes in the documentation.

What are Fallow’s complexity and health metrics?

This section focuses on code complexity metrics for individual functions and files. It measures how difficult different parts of your codebase are to understand and maintain.

The report is organized into several subsections that highlight files with large functions, highly complex functions, low file health scores, and other maintainability concerns.

How does Fallow identify large functions?

The Large Functions section lists every function that exceeds Fallow‘s size threshold, along with its location in the codebase. For each entry, it shows the function name, the starting line, and the total line range.

Using the first entry in the example above, we can see that the signup.tsx file contains a signupForm function that starts on line 13 and spans 196 lines.

How does Fallow measure code complexity?

The High Complexity Functions section can look intimidating at first, but it simply measures how difficult a function is to understand, maintain, and test. Fallow reports three complexity metrics for each function:

  • Cyclomatic: The cyclomatic complexity score indicates how many different branches there are in a function. What this essentially means is that every time you have an if statement, a ternary, or a switch statement in your code, it adds to the cyclomatic complexity count. In the example above, the handleSubmit function has a cyclomatic complexity of 7, meaning it contains seven execution paths, which is still a reasonable score
  • Cognitive: This measures how difficult a function is to read and understand. Deep nested if statements, loops, and other control-flow structures increase the cognitive complexity because they make the code harder to follow. In the example, the handleSubmit function has a cognitive complexity of 4
  • CRAP: The CRAP (Change Risk Anti-Patterns) score combines a function’s complexity with its test coverage. A complex function with little or no test coverage receives a high CRAP score, while a similarly complex function with good test coverage scores much lower. In the example above, the handleSubmit function has a high CRAP score because it’s relatively complex and doesn’t have corresponding tests

How does the File Health Score work?

The File Health Score section provides an overall assessment of each file’s maintainability. It takes several factors into account, including the file’s complexity, the amount of dead code it contains, the number of files it imports, and how many other files depend on it.

These metrics are combined to produce a health score and an associated risk level. The risk score is influenced by multiple factors, with high CRAP scores contributing significantly because they indicate complex code with insufficient test coverage.

What are Hotspots in Fallow?

The Hotspots section identifies the files that are most likely to become maintenance problems over time. It analyzes your Git history to determine which files change most frequently and combines that information with each file’s maintainability metrics.

This is because a complex file that is modified in almost every pull request is far more likely to accumulate bugs and technical debt than one that’s rarely touched.

As a result, files that change frequently and have poor maintainability scores are ranked highest in the Hotspots report.

How does Fallow identify refactoring targets?

This is the final section of the report. It provides a ranked list of the best places to start refactoring based on the effort required and the potential impact.

Files are ranked using a combination of complexity, duplication, and dead code metrics, helping you identify the changes that are likely to deliver the greatest return for the least amount of work.

Think of this section as a high-level cleanup roadmap. Instead of focusing on individual issues, it helps you decide where to invest your refactoring effort first.

How do you configure Fallow?

Although Fallow doesn’t require any configuration to generate a useful report, as we’ve seen in the previous sections, it can occasionally produce false positives, particularly in the Dead Code and Duplication reports.

This happens because static analysis can’t always distinguish intentional patterns from actual issues. For example, duplicated code in test files, repeated data structures, or application entry points may be flagged as duplicate or unused even though they’re required.

To reduce these false positives, you can create a configuration file. This allows you to specify your project’s entry points, define files and directories to ignore, and customize other settings so Fallow can produce more accurate results.

npx fallow init

This command generates a .fallowrc.json file in your project’s root directory. Open the file, set your project’s entry points, and add any files or directories you want Fallow to ignore to the ignorePattern field, as shown below:

{
   "$schema":      "
  "entry": ["src/workers/*.ts", "scripts/*.ts"],
   "ignorePatterns": [
    "src/data/data/**",
    "**/*.generated.ts",
    "**/__tests__/**"
    ]
 }

You can also configure the severity of individual rules on a per-file basis, or disable rules you’re not ready to enforce by setting their severity to off. Fallow also lets you customize its duplication detection mode and many other aspects of its analysis.

{
    "rules": {
    "unused-files": "error",
    "unused-exports": "warn",
    "unused-types": "off",
  },
  "duplicates": {
    "mode": "mild",
    "minTokens": 50,
    "minLines": 5,
    "threshold": 10
  },
}

In cases where you have unused exports that are consumed by external projects and therefore have no internal references, you don’t have to exclude the entire file. Instead, you can use Fallow‘s inline suppression comments (fallow-ignore) or JSDoc visibility tags to selectively ignore those exports.

// Suppress all issues on the next line
// fallow-ignore-next-line
export const keepThis = 1;
// Suppress a specific issue type
// fallow-ignore-next-line unused-export
export const keepThisToo = 2;

Fallow recognizes four JSDoc visibility tags: @public, @internal, @beta, @alpha:

/** @public */
export function createClient() {
  // Not imported anywhere in this repo, but consumed by users of the library
}
/** @internal */
export function resetState() {
  // Used by sibling packages in the monorepo, not public API
}

Fallow also provides the @expected-unused JSDoc tag for exports that are intentionally unused. Unlike visibility tags, this annotation is tracked. If the export is eventually referenced, Fallow marks the tag as stale, letting you know it’s no longer needed and can be removed.

/** @expected-unused */
export const deprecatedHelper = () => {
  // Intentionally kept but not used anywhere
};

To learn more about inline suppressions and the many ways you can configure Fallow, refer to the documentation.

Integrating Fallow into your workflow

Where Fallow really shines is its integration with AI-assisted development workflows. The idea is to instruct your coding agent to run Fallow against every newly implemented feature and use the report to fix any issues before considering the task complete.

Every Fallow command accepts the --format json flag, which returns a structured JSON object that AI agents can easily parse. For example, running the default fallow command with the flag:

npx fallow --format json

Executes every analysis combined: dead code, duplication, and health metrics, and returns a single JSON report like the one in the image below.

The returned JSON object includes an actions array containing suggested fixes, along with an auto_fixable flag that tells the agent whether an issue can be resolved automatically. This allows the agent to decide whether to run fallow fix –yes for straightforward fixes or implement the changes manually when needed.

You can then instruct your AI agent, either through an agent.md file or manually, to run Fallow with the --format json flag before every commit, ensuring new code meets your project’s quality standards.

How do you use the Fallow AI skill?

An even better option is to install Fallow‘s official AI skill if your coding agent supports it. The skill gives the agent access to Fallow‘s commands directly, so it doesn’t have to guess which commands to run or how to use them.

You can install it in Claude through the plugin marketplace or by running the following command:

/plugin marketplace add fallow-rs/fallow-skills
/plugin install fallow-skills@fallow-rs/fallow-skills

For Codex, Copilot, Cursor, and other supported agents, install the skill into the agent’s respective skills directory using the following command:

git clone 

Once the skill is installed, the agent can automatically choose the appropriate Fallow analysis, Dead Code, Duplication, or Health, based on the task you’ve given it. It then uses the results to perform the actions you’ve instructed, whether that’s fixing issues, refactoring code, or generating recommendations.

How do you use the fallow-mcpserver?

Another way to integrate Fallow into your workflow is by installing the fallow-mcp server, provided your AI client supports MCP. Once installed, all you need to do is add the following configuration to your client’s MCP settings:

{
  "mcpServers": {
    "fallow": {
      "command": "fallow-mcp"
    }
  }
}

With that in place, your agent will have access to tools such as analyze, check_changed, and find_dupes, which allow it to inspect your codebase and return structured results that it can act on.

How do you integrate Fallow into a CI/CD pipeline?

While your AI agent will generally follow Fallow‘s recommendations and the policies you’ve configured, it won’t always get it right. It’s still an AI, and there may be times when it ignores an issue, proceeds with the implementation, and pushes code that shouldn’t make it into production.

To guard against this, you can add Fallow as a final quality gate in your CI/CD pipeline. This ensures every change is analyzed before it’s merged or deployed, even if your AI agent fails to follow your instructions.

Fallow integrates with virtually any CI platform. For example, to use it with GitHub Actions, simply add the following code to your workflow file:

name: Fallow analysis
on: [push, pull_request]


jobs:
  fallow:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: fallow-rs/fallow@v2
        with:
          format: sarif

With this in place, your CI pipeline will catch dead code, duplication, complexity, and other code quality issues that slip past your AI agent or manual review on every push or pull request.

For instructions on integrating Fallow with other CI platforms and customizing its configuration, refer to the documentation.

Conclusion

In this article, you learned how to use Fallow to analyze your codebase, identify dead code, duplicate logic, and maintainability issues, and integrate those insights into your AI-assisted development workflow.

Fallow offers far more than we’ve covered here, with additional configuration options, analysis modes, and integrations to suit different projects and workflows. Explore the documentation to customize its behavior and make it a regular part of your development process. As AI-generated code becomes more common, tools like Fallow can help ensure your codebase stays clean, maintainable, and easy to evolve.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

AI coding agents have a tendency to generate code that isn’t particularly maintainable. They often duplicate logic, create massive files, and produce overly complex functions that are difficult for humans to understand. As these issues accumulate over time, they can turn a codebase into a significant maintenance burden. In many cases, asking an agent to refactor simply results in even

How AI changed the way I approach design critiques

When AI made generating design concepts almost effortless, I realized the most valuable part of a critique was no longer the interface itself. It was understanding the context, tradeoffs, and judgment behind the final design. Here’s how AI has changed the way I run design critiques—and why I think that’s making them better.

Double Diamond Symbol

What is the Double Diamond design process?

The Double Diamond design process helps UX teams balance exploration with decision-making, guiding projects from problem discovery to solution delivery. Learn how each phase works, which tools to use, when the reverse Double Diamond makes sense, and why the framework remains relevant for modern product development.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

How AI changed the way I approach design critiques When AI made generating design concepts almost effortless, I realized the most valuable part of a critique was no longer the interface itself. It was understanding the context, tradeoffs, and judgment behind the final design. Here’s how AI has changed the way I run design critiques—and why I think that’s making

The PM world runs on frameworks like RICE, JTBD, OKRs, Kano, and MoSCoW. These frameworks have become popular because they offer a packaged way to solve a problem through a neat, repeatable process. However, while they might give you clean, ranked answers, they often aren’t tailored to your unique context and can cause you to miss the mark.

I learned this the hard way. I once inherited a freemium product with more than 50 conversion entry points scattered across the funnel. I ran a textbook prioritization pass: I scored everything, sorted the list, and presented the top item with total confidence.

It was wrong. Not “we disagree” wrong, but factually missing the point wrong. The scoring framework flattened 50 conversion moments into a single ranking and ignored what mattered most. The math was clean, but the conclusion was garbage.

Here’s the reframe the whole article hangs on: your framework isn’t the work. The read is. Read your context before you reach for a tool, bend the tool to your reality, and drop the whole shelf when nothing fits.

Why generic product management frameworks fail

Frameworks break because your situation lives in the context they abstract away. There are three main ways they go wrong.

Subjective scoring creates the illusion of objectivity

RICE, ICE, and weighted scoring promise math but often deliver opinions dressed up as math. Your “impact = 7” is my “impact = 4,” and neither rating can be proven. A number you can’t defend isn’t evidence of product rigor.

Framework theater prioritizes process over outcomes

Rename the PM “Product Owner.” Set up the Jira board. Go through all the motions without delivering the outcomes.

I’ve watched teams write OKRs in January, file them away, and not reopen the document until December. Then, they backfill the key results to match what actually happened.

The framework doesn’t match the product stage or business model

A startup isn’t a miniature big company. Run a B2C growth playbook in an enterprise sales environment and watch it faceplant. This is also why “universal” methodologies deserve some side-eye.

The common thread is that a framework is a starting hypothesis, not an answer. Treat it as the answer, and it stops working for you and starts working on you.

How to choose the right product management framework

Choosing the framework is the easiest 20 percent. Reading the situation is the other 80 percent, and almost nobody does it. Before reaching for a template, ask a few questions:

Product Framework Context Diagnostic



Identify the type of product problem

Borrowing from the Cynefin framework, ask whether cause and effect are knowable or only emergent. If the problem is complicated, such as reprioritizing a known backlog, a framework like RICE can help. If it’s complex, such as predicting whether a feature will change behavior in a market that doesn’t yet exist, no framework can give you the answer.

Assess whether the decision is reversible

This is Bezos’ one-way versus two-way door distinction, one of the most underused filters in product management.

Is the decision irreversible and expensive, such as changing your pricing model, rebuilding the core architecture, or making a public commitment? Slow down, use a more rigorous framework, and run a pre-mortem.

Is it reversible and inexpensive, such as changing a button color or adjusting a feature flag? Decide and move on. Most apparent one-way doors are actually two-way doors. Learn to spot the difference, and half your process bloat vanishes.

Account for your product stage and constraints

Pre-PMF, scaling, and mature products operate in different worlds with different physics. Then, add the boring constraints: budget, team capabilities, and regulatory realities. A framework that assumes you have a data team is useless if you don’t have one.

Determine whether the problem involves strategy, execution, or perception

Sort the problem by altitude: strategy, execution, or perception. I’ve burned the better part of a quarter RICE-scoring a backlog when we’d chosen the wrong strategy. We were executing the wrong list faster, with prettier scores.

Diagnose the altitude first, or you’ll bring an execution tool to a strategy fight.

Your output should be a paragraph rather than a decision: This is a complex, hard-to-reverse, pre-PMF strategy problem for a small team with no analytics. That diagnosis tells you whether any framework deserves a seat and, if so, which one.

How to adapt a product management framework to your context

Now, and only now, do you open a template. Every candidate receives one of three verdicts: use it as is, which is rare; adapt it; or skip it:

Fit Bend Drop Product Framework

Customize the inputs and weights

RICE is an easy example because everyone misuses it in the same way: Reach gets flattened into one number, Confidence becomes a reflexive 100 percent, and Effort is based on a gut estimate that ends up being off by 40 percent. Garbage in, confident garbage out.

Using RICE properly means rebuilding the framework around your reality. Calculate Reach by customer segment. Split Effort into the components that actually vary, such as engineering time, design time, and QA overhead. Tie Confidence to evidence and define Impact according to your intended outcomes.

This is where tailoring starts to matter. At Brainly, the standard funnel assumed that the user was also the buyer. The problem was that most users were teenagers, and teenagers weren’t the ones pulling out a credit card. Their parents were.

Reweighting the framework around the actual buyer flipped the ranking. Features that had been dead last jumped to the top. It was the same framework with the opposite answer.

Combine frameworks that answer different questions

Frameworks answer different questions, so stop forcing one framework to do everything. JTBD is useful for discovery because it identifies what people are trying to accomplish. RICE can help with prioritization by identifying what to build first.

Run JTBD first, then apply RICE to the job you uncovered, not the original feature list.

Adjust the cadence and expectations

OKRs at a 12-person pre-PMF startup shouldn’t look like OKRs at a 2,000-person scale-up. Early on, they’re about validation, and the right cadence might be monthly. At scale, quarterly growth OKRs can make sense.

Apply an enterprise cadence at a startup, and you’ll find yourself optimizing against assumptions that became outdated weeks ago.

Sometimes, the generic rule needs to be inverted entirely. Consumer product orthodoxy says to reduce friction, show fewer ads, and make users happier. On one adtech platform with well over 100 million monthly active users, we did the opposite: We showed more ads, more often.

Complaints should have spiked. Instead, they dropped because we paired the increase with better targeting. The generic advice wasn’t merely wrong. The right move was the reverse.

Document what you changed and why

One guardrail is nonnegotiable: Document what you changed and why. For example, “We use RICE with custom weights because a flat Reach score misrepresents our multi-segment market.”

A documented modification invites scrutiny. An undocumented one pretends to be objective. I go deeper into matching your operating model to your context in my guide to choosing a product team structure.

What to do when no product management framework fits

Sometimes, you run the diagnosis, audit every template, and find that nothing fits. Anyone can apply a framework. Knowing when to throw them all out is what you’re paid for.

Reason from first principles

Kill the reflex to ask, “What did the last company do?” or “What does the framework say?” Both answers are someone else’s context dressed up in your problem’s clothes.

At Brainly, “the user is the buyer” was the inherited lie. The load-bearing fact was that a 14-year-old user wasn’t the one entering the payment details. A parent was. Find the load-bearing facts, then build your reasoning from them. It’s slower, but sometimes it’s the only approach that works.

Test assumptions with a low-cost experiment

In complex domains, you discover the answer rather than reason your way to it, so make discovery cheap. On the adtech platform, we tested the higher ad load with two percent of its more than 100 million users for one week before rolling it out broadly.



One toggle gave us real data about complaints. The alternative was spending a quarter in meetings arguing about whether users would revolt.

That’s why skipping discovery and going straight to building backfires. The goal is to learn quickly and cheaply.

Use a pre-mortem and decision journal

Before committing, run a pre-mortem. Assume it’s six months later and the decision has failed, then work backward out loud to identify why.

Those answers expose your risks. Turn them into kill criteria by defining two or three conditions that would cause you to walk away. Record the hypothesis, key assumptions, and kill criteria in a decision journal, then set a reminder to revisit them in four weeks.

Do this often enough, and you stop needing the framework because you’ve internalized what it was helping you do. Take estimation. After years of making the same kind of weekly estimate for one product, I could make a five-minute gut call that was accurate roughly 80 percent of the time because my judgment had been calibrated against what actually shipped.

This is also why story points break when you misapply them. The number means nothing until the team behind it is calibrated.

Product frameworks should support judgment, not replace it

The framework is the easy part. The hard 80 percent is reading your messy context first. A sound diagnosis can make a mediocre framework useful. A bad diagnosis can lead the best framework on the internet to confidently rank your worst idea first in a clean spreadsheet.

Frameworks still have a place, but they can’t do the thinking for you. Read the context, make the judgment call, and use the tool to sharpen it.

Featured image source: IconScout


LogRocket generates product insights that lead to meaningful action


Plug image


LogRocket identifies friction points in the user experience so you can make informed decisions about product and design changes that must happen to hit your goals.

With LogRocket, you can understand the scope of the issues affecting your product and prioritize the changes that need to be made. LogRocket simplifies workflows by allowing Engineering, Product, UX, and Design teams to work from the same data as you, eliminating any confusion about what needs to be done.


Get your teams on the same page — try LogRocket today.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

The PM world runs on frameworks like RICE, JTBD, OKRs, Kano, and MoSCoW. These frameworks have become popular because they offer a packaged way to solve a problem through a neat, repeatable process. However, while they might give you clean, ranked answers, they often aren’t tailored to your unique context and can cause you to miss the mark. I learned

AI coding agents are useful, but they have a familiar failure mode: They often solve modern frontend problems with legacy patterns.

Ask an agent to build a modal, tooltip, responsive card layout, or long-running search interaction, and it may reach for extra JavaScript, older browser APIs, or another dependency. Sometimes that is the right tradeoff. But often, the browser can already solve the problem with native HTML, CSS, or platform APIs.

That gap exists because the web platform changes faster than model training data. New features ship, syntax changes, browser support improves, and best practices evolve. A model may not know the feature exists, or it may know about the feature but use outdated syntax or recommend fallbacks your project does not need.

Chrome’s Modern Web Guidance is designed to close that gap. It is a set of agent skills from the Chrome team that embeds modern web platform guidance, browser compatibility data, and best practices directly into AI coding workflows. Instead of relying only on the model’s training data, your agent can retrieve relevant guidance before it writes code.

In this article, we’ll set up Modern Web Guidance, configure a browser support target, and compare two generated task manager apps: one built with a standard AI coding agent and one built with Modern Web Guidance enabled. The goal is not to prove that native APIs are always better than libraries. It is to show how better guidance can help agents choose simpler, more current frontend solutions when the platform already supports them.

Prerequisites

To follow along, you’ll need:

    • A supported AI coding agent, such as Antigravity, Gemini CLI, Claude Code, Copilot CLI, or another tool that supports agent skills
    • A frontend project to test against. This article uses a React/Next.js project, but the guidance itself is not React-specific

Why AI coding agents ship legacy web code

Large language models have a basic limitation: Their knowledge has a cutoff date. Even when an agent can search or retrieve documentation, it may still default to familiar patterns from its training data unless the workflow explicitly tells it to check modern platform guidance.

This creates two common failure modes:

    • The agent does not know a newer browser feature exists. For example, it may install a tooltip library instead of considering CSS Anchor Positioning or the Popover API.
    • The agent knows the feature exists, but uses the wrong syntax or support assumptions. This can lead to broken attributes, incomplete fallbacks, or code that works only in a narrow browser target.

Legacy code has real costs. It can increase bundle size, add maintenance overhead, introduce more failure points, and make performance harder to reason about. Over time, those small choices accumulate into a frontend that is more complex than it needs to be.

You might assume that retrieval-augmented generation (RAG) solves this. RAG can help, but it still pushes a lot of work onto the developer. You have to find the right documentation, keep it current, and make sure the model can reason over it correctly for each task.

Modern Web Guidance takes a more structured approach. It packages expert-curated guidance into skills that an agent can discover and retrieve as part of its normal coding loop.

At a high level, it helps agents:

    • Avoid outdated frontend patterns
    • Prefer native HTML, CSS, and browser APIs when they are a good fit
    • Apply accessibility and UI guidance more consistently
    • Consider performance metrics such as Interaction to Next Paint (INP) and Largest Contentful Paint (LCP)
    • Follow security best practices around areas such as Content Security Policy (CSP), cookies, and cross-origin isolation
    • Match recommendations to the project’s declared browser support target

What Modern Web Guidance changes in practice

Without Modern Web Guidance, an agent may treat a native browser feature as an edge case and solve the problem with a dependency. With Modern Web Guidance, the same agent is more likely to ask: “Can the platform do this already?”

That difference matters because it changes the default decision path. The agent can still choose a library when browser support, product requirements, or team constraints make that the better option. But the library is no longer the automatic first answer.

Modern Web Guidance covers several areas of frontend development:

Discipline What the agent can retrieve guidance on
User experience View Transitions, entry and exit animations, scroll-driven effects, and native interaction patterns
CSS layout Container queries, subgrid, anchor positioning, intrinsic sizing, and modern color spaces like oklch
Performance INP diagnostics, scheduler.yield(), background task scheduling, and image/resource prioritization
Forms and UI Native <dialog>, the Popover API, form validation states, and accessible UI behavior
Accessibility Focus management, semantic HTML, accessible errors, keyboard behavior, and ARIA usage
Security and privacy CSP, cookies, cross-origin isolation, data minimization, and safer defaults
Built-in AI On-device translation, summarization, and language detection APIs where available

Chrome’s documentation describes Modern Web Guidance as an early preview, so treat it as a fast-moving tool rather than a static reference. That makes the installation and update path important.

Setting up Modern Web Guidance

The recommended installation path is the modern-web-guidance CLI, which installs the skill files and keeps them updated.

Open your terminal and run:

npx modern-web-guidance@latest install

The installer guides you through setup and lets you choose where the skills should be available. Depending on your workflow, you can install the guidance globally or into a specific project.

A project-level install is a good default when you want the guidance to travel with one codebase. A global install is useful if you want the same guidance available across multiple projects and agents on your machine.



Install directly into a specific agent

You can also install Modern Web Guidance directly for specific coding agents.

For Gemini CLI, run:

gemini extensions install  --auto-update

For Antigravity CLI, run:

agy plugin install 

For Claude Code, add the marketplace, install the plugin, and reload plugins:

/plugin marketplace add GoogleChrome/modern-web-guidance
/plugin install modern-web-guidance@googlechrome
/reload-plugins

For Copilot CLI, add the marketplace and install the plugin:

/plugin marketplace add GoogleChrome/modern-web-guidance
/plugin install modern-web-guidance@googlechrome

For GitHub CLI, run:

gh skill install GoogleChrome/modern-web-guidance

For Vercel Skills, run:

npx skills add GoogleChrome/modern-web-guidance

The exact install path depends on the agent, but the result is the same: Your coding agent gains access to a skill that can search and retrieve modern web platform guidance before implementing a task.

Verify the installation

After installation, confirm that the skill is available to your agent. Depending on your install method, you may see generated skill files in your project or user-level agent configuration directory.

Modern Web Guidance also exposes CLI commands you can use to explore the guide library directly. For example, you can search for guidance on animating a dialog modal:

npx modern-web-guidance@latest search "animate a dialog modal backdrop"

Then retrieve a specific guide by ID:

npx modern-web-guidance@latest retrieve "animate-to-from-top-layer"

This is useful even before you wire the skill into an agent. It lets you inspect the guidance your agent will receive and verify that the relevant use cases exist for the feature you are building.

Set a Baseline target

Modern Web Guidance is most useful when it knows what browsers your project supports. Otherwise, it has to be conservative.

By default, Modern Web Guidance targets Baseline Widely available. That means the agent will usually include progressive enhancement patterns, fallbacks, or conditional loading where a feature is not broadly supported.

If your project targets a newer browser set, declare that explicitly in your agent instruction file, such as AGENTS.md, CLAUDE.md, or .gemini/GEMINI.md:

This project's Baseline target is Baseline 2024.

You can also add project-specific support context:

# Browser support target

This project's Baseline target is Baseline 2024.
Prefer native browser APIs when they meet this target.
Use progressive enhancement for newer or limited-availability features.

This helps the agent decide when it can use a modern feature directly and when it should include a fallback. For example, an internal dashboard locked to recent Chromium browsers can make different choices than a public consumer app that needs broad Safari and Firefox support.

The important part is that the browser target becomes part of the agent’s context. Without it, the agent may either over-polyfill or use a feature too aggressively.

Testing Modern Web Guidance in a sample app

To see what Modern Web Guidance changes in practice, I created two copies of the same initialized Next.js project:

  • taskmanager1: Built without Modern Web Guidance
  • taskmanager2: Built with Modern Web Guidance enabled

I used Gemini CLI with the same model settings in both environments and gave both agents the same prompt:

Build a Task Manager app. It should have:

- A modal for adding tasks with smooth entrance and exit animations.
- Task cards that stack vertically in a sidebar but show full details in the main area.
- A search bar that filters 2,000 tasks without lagging the UI.
- A Help tooltip tethered to the Status icon that flips if it hits the viewport edge.

Task Manager prompt entered in Gemini CLI terminal interface

The same prompt was run against two copies of the project: one without Modern Web Guidance and one with the skill enabled.

The most interesting difference was not just the final code. It was the agent’s decision process.

Without Modern Web Guidance, the agent treated UI complexity as a signal to add libraries. With Modern Web Guidance installed, the agent added a research step to look for relevant browser-native patterns before implementing the feature.

Modern Web Guidance agent research step showing retrieved platform guidance before implementation

With Modern Web Guidance enabled, the agent retrieved relevant platform guidance before choosing an implementation approach.

Comparing the results

Here is how the two builds differed:

Feature taskmanager1 without guidance taskmanager2 with guidance
Modal animation Used a custom modal implementation with JavaScript state and transition timing Used native <dialog> with modern CSS entry/exit animation patterns
Task cards Used media queries, which made the layout dependent on viewport width Used CSS Container Queries, so cards adapted to the sidebar container
Search filter Used React memoization and timer-based logic, but still relied on synchronous filtering Used scheduler.yield() to break work into chunks and keep the UI responsive
Help tooltip Used a floating UI dependency for positioning and edge flipping Used CSS Anchor Positioning where supported by the project target

The biggest change was dependency pressure. In taskmanager1, the agent added extra JavaScript to solve UI interactions that the browser can increasingly handle on its own. In taskmanager2, the agent used the Modern Web Guidance skill to identify native equivalents and avoid additional UI positioning and animation packages for these features.

That does not mean every app should remove every UI dependency. Libraries still matter when you need broader browser support, mature accessibility abstractions, complex design-system behavior, or consistent cross-framework APIs. The point is that the agent made a more informed tradeoff.

The tooltip requirement asked for a Help tooltip tethered to the Status icon that flips when it reaches the viewport edge.

Without Modern Web Guidance

The unguided agent installed a positioning library and wrote a hook-based component:

import { useFloating, flip, shift, offset } from '@floating-ui/react';

export function StatusTooltip({ children }) {
  const { refs, floatingStyles } = useFloating({
    placement: 'top',
    middleware: [offset(10), flip(), shift()],
  });

  return (
    <>
      <div ref={refs.setReference} className="status-icon">i</div>
      <div ref={refs.setFloating} style={floatingStyles} className="tooltip">
        {children}
      </div>
    </>
  );
}

This is not inherently wrong. Floating UI is a strong option when you need robust positioning across browsers and complex interactions. But for a simple tooltip in a modern-browser target, it may be more than the feature requires.

With Modern Web Guidance

The guided agent recognized CSS Anchor Positioning as a possible fit. A simplified version looks like this:

export function StatusTooltip({ children }) {
  return (
    <>
      <div className="status-icon">i</div>
      <div className="tooltip" role="tooltip">
        {children}
      </div>
    </>
  );
}
.status-icon {
  anchor-name: --status-icon;
}

.tooltip {
  position: absolute;
  position-anchor: --status-icon;
  position-area: top;
  position-try-fallbacks: flip-block;
  margin-bottom: 10px;
}

The implementation moves positioning work out of JavaScript and into CSS. That makes the code smaller and easier to inspect. However, this is also where the Baseline target matters. If your app needs browsers that do not fully support CSS Anchor Positioning, you still need a progressive enhancement strategy or a library fallback.

Code comparison: Modal animation

The modal requirement asked for smooth entrance and exit animations. The two builds solved that at different layers of the stack.

Without Modern Web Guidance

The unguided agent used createPortal, a shouldRender flag, and a setTimeout to keep the modal mounted long enough for the exit animation to finish:

export const Modal = ({ isOpen, onClose, title, children }: ModalProps) => {
  const [shouldRender, setShouldRender] = useState(isOpen);

  useEffect(() => {
    if (isOpen) {
      setShouldRender(true);
      document.body.style.overflow = 'hidden';
    } else {
      const timer = setTimeout(() => {
        setShouldRender(false);
        document.body.style.overflow = 'auto';
      }, 300);

      return () => clearTimeout(timer);
    }
  }, [isOpen]);

  if (!shouldRender) return null;

  return createPortal(
    <div className={`${styles.overlay} ${isOpen ? styles.open : ''}`} onClick={onClose}>
      <div
        className={`${styles.modal} ${isOpen ? styles.open : ''}`}
        onClick={(event) => event.stopPropagation()}
      >
        {children}
      </div>
    </div>,
    document.body
  );
};

The fragile part is the 300 millisecond timer. The JavaScript timeout and the CSS transition duration have to stay in sync manually. If someone changes the animation duration in CSS, the JavaScript can fall out of sync.

With Modern Web Guidance

The guided version used the native <dialog> element and let the browser handle top-layer behavior. In React, you still need a small amount of JavaScript to open and close the dialog, but you no longer need a custom render timer or portal layer:

import { useEffect, useRef } from 'react';

export function TaskModal({ open, onClose, children }: TaskModalProps) {
  const dialogRef = useRef<HTMLDialogElement>(null);

  useEffect(() => {
    const dialog = dialogRef.current;
    if (!dialog) return;

    if (open && !dialog.open) {
      dialog.showModal();
    }

    if (!open && dialog.open) {
      dialog.close();
    }
  }, [open]);

  return (
    <dialog ref={dialogRef} onClose={onClose}>
      <form method="dialog">
        {children}
        <button type="submit">Create task</button>
        <button type="button" onClick={() => dialogRef.current?.close()}>
          Cancel
        </button>
      </form>
    </dialog>
  );
}

Then CSS handles the entry and exit animation:

dialog {
  opacity: 0;
  transform: scale(0.96);
  transition:
    display 0.4s,
    overlay 0.4s,
    opacity 0.4s ease,
    transform 0.4s ease;
  transition-behavior: allow-discrete;
}

dialog[open] {
  opacity: 1;
  transform: scale(1);
}

@starting-style {
  dialog[open] {
    opacity: 0;
    transform: scale(0.96);
  }
}

dialog::backdrop {
  background: rgb(0 0 0 / 40%);
}

There is no render timeout to maintain. The browser’s top layer handles important modal behavior, including focus handling and backdrop rendering. You should still test keyboard behavior, focus return, and screen reader output, but the implementation starts from a stronger native primitive.

Code comparison: Search performance

The prompt asked for a search bar that filters 2,000 tasks without lagging the UI. This is an INP problem: if a synchronous loop blocks the main thread, the browser cannot respond to input or paint the next frame until the work finishes.

Without Modern Web Guidance

The unguided agent wrapped the filter in useMemo:

const filteredTasks = useMemo(() => {
  return tasks.filter((task) =>
    task.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
    task.description.toLowerCase().includes(searchTerm.toLowerCase())
  );
}, [tasks, searchTerm]);

useMemo avoids unnecessary recalculation across renders, but it does not make the filtering work non-blocking. When searchTerm changes, the full filter still runs synchronously on the main thread. This is one of the React patterns that quietly kills performance at scale.

With Modern Web Guidance

The guided agent used scheduler.yield() to break the loop into smaller chunks. That gives the browser a chance to handle user input and paint between batches:

useEffect(() => {
  let cancelled = false;

  const filterTasks = async () => {
    setIsFiltering(true);

    const query = searchQuery.toLowerCase();
    const results: Task[] = [];

    for (let index = 0; index < tasks.length; index++) {
      if (index > 0 && index % 50 === 0) {
        if ('scheduler' in window && 'yield' in window.scheduler) {
          await window.scheduler.yield();
        } else {
          await new Promise(requestAnimationFrame);
        }
      }

      const task = tasks[index];
      const title = task.title.toLowerCase();
      const description = task.description.toLowerCase();

      if (title.includes(query) || description.includes(query)) {
        results.push(task);
      }
    }

    if (!cancelled) {
      setFilteredTasks(results);
      setIsFiltering(false);
    }
  };

  filterTasks();

  return () => {
    cancelled = true;
  };
}, [searchQuery, tasks]);

The important change is not just the API choice. The agent reasoned about the interaction as a responsiveness problem rather than a React rendering problem. That led to a different implementation strategy: split long work so the browser can keep responding.

For production, you would still test this with realistic data and devices. For very large datasets, server-side search, indexing, virtualization, or a Web Worker may be more appropriate. But for this demo, Modern Web Guidance moved the agent toward the right performance question.

Where you still need developer judgment

Modern Web Guidance improves the agent’s starting point, but it does not remove the need for review. The guidance can help an agent discover modern browser features, but you still need to validate whether those choices fit your product.

Before shipping AI-generated frontend code, review the following:

Question Why it matters
Does this match our browser support target? A native API may be appropriate for an internal Chrome-only app but risky for a broad public audience.
Is the fallback strategy clear? Newer features often need progressive enhancement or conditional loading.
Is the accessibility behavior complete? Native elements help, but you still need to test keyboard behavior, focus order, labels, and announcements.
Did the agent reduce complexity or just move it? A smaller dependency list is only useful if the resulting code is easier to maintain.
Did we test the actual user path? Generated code can look modern while still failing in edge cases.

This is the right mental model: Modern Web Guidance helps the agent ask better questions. It does not replace code review, browser testing, or product-specific tradeoff decisions.

Conclusion

AI coding agents are only as good as the context they use. Without current web platform guidance, they often reach for familiar solutions: extra dependencies, JavaScript-heavy UI code, or older patterns that made sense before newer browser APIs were available.

Chrome’s Modern Web Guidance gives those agents a more current decision path. In the task manager demo, that changed the output in concrete ways: The agent used native <dialog> patterns for modal behavior, CSS Container Queries for component-level responsiveness, CSS Anchor Positioning for the tooltip, and scheduler.yield() to keep filtering responsive. The result was not just less code. It was a different default: check what the browser can do first, then add a dependency only when the project actually needs one.

The main takeaway is not that native APIs should always replace libraries. The takeaway is that AI-generated code needs modern constraints. Install the guidance, declare your Baseline target, and review the output against your real browser support, accessibility, and performance requirements.

You can explore the source code for both demo applications below:

  • taskmanager1: The implementation generated without Modern Web Guidance
  • taskmanager2: The implementation generated with Modern Web Guidance enabled

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

AI coding agents are useful, but they have a familiar failure mode: They often solve modern frontend problems with legacy patterns. Ask an agent to build a modal, tooltip, responsive card layout, or long-running search interaction, and it may reach for extra JavaScript, older browser APIs, or another dependency. Sometimes that is the right tradeoff. But often, the browser can

Last month I dived back into the foreign exchange market and noticed a little gap in how lot sizes are calculated and how slow that can be. To be sincere, as a developer, I didn’t even bother looking for an existing tool online, cause if it’s free, then there will be so many ads, and I’m not the biggest fan of ads. I spun up a position-size calculator in Next.js and shipped it.

If I were to document how to use the app, Remotion would be the first that crossed my mind, cause with it I can write the videos in React, render them to MP4 from my terminal, and the whole thing will take less time than one screen recording session used to. When the design changes a week later, I will change two lines of mock data and re-render.

In this article, I’ll walk through the actual build: how I adapted an existing Next.js app for Remotion, built three production demo videos, and used Remotion’s AI agent integration to generate a fourth composition from a natural-language prompt. I’ll also address the setup cost head-on, because it’s real and you should know about it before you commit.

What is Remotion?

Remotion treats video as a React application. You write JSX, use useCurrentFrame() to get the current frame number, animate values with interpolate() and spring(), and compose scenes with <Sequence>. The output is a real PNG and MP4 rendered via headless Chrome and FFmpeg.

If you’ve used React, you already know 80% of what you need. The remaining 20% is these three APIs:

  • useCurrentFrame(): This returns the current frame number. This is your clock
  • interpolate(frame, inputRange, outputRange): This maps frame numbers to values. This is how you animate
  • <Sequence from={60} durationInFrames={150}>: This wraps a section of your composition in a time window. This is how you choreograph

Remotion Studio gives you a browser-based preview with timeline scrubbing and hot reload. You see your video update as you write code, the same way you see a React app update in dev mode.

Remotion is not new, but most React devs still don’t know it exists because every existing article is either a docs walkthrough or a showcase of fancy animations. Nobody has taken a real product demo workflow and documented how Remotion replaces the screen recorder with code.

That’s what this piece does.

What does it take to set up Remotion?

One command to render a video sounds clean, but getting there requires adapting your app components for Remotion’s rendering environment. Here’s what that actually looks like.

Why do Remotion components need to be pure?

Remotion renders each frame as a static React component. That means there are no useState, useEffect, event listeners, browser APIs like localStorage, and Next. js-specific features like useRouter. Your components need to read everything from props.

For my calculator app, this meant creating adapted versions of four components. The original Calculator component had reactive state management, keyboard listeners, and localStorage for history tracking. The Remotion version, RemotionCalculator, strips all of that and reads input values directly from props:

// Original: manages its own state
const Calculator = () => {
  const [accountSize, setAccountSize] = useState(10000);
  const [riskPercent, setRiskPercent] = useState(2);
  // ... event handlers, localStorage, etc.
};

// Remotion version: pure component, reads from props
const RemotionCalculator = ({
  accountSize,
  riskPercent,
  stopLoss,
  pair,
}: CalculatorProps) => {
  const result = calculate(accountSize, riskPercent, stopLoss, pair);
  // ... render with result, no state needed
};

The ResultsCard, PairSelector, and RiskQuickSelect components needed similar treatment. Total adaptation time: about 15 minutes. The shared calculation logic in lib/calculate.ts worked in both environments without changes, which is exactly why keeping business logic in pure functions pays off.

Why does Remotion use mock data?

Screen recording uses your live app. Remotion uses mock data passed as props. For each demo video, I created a mock file with the exact values I wanted to show:

// remotion/mocks/featureWalkthroughMocks.ts
export const calculatorStates = {
  initial: { accountSize: 0, riskPercent: 0, stopLoss: 0, pair: 'EUR/USD' },
  filled: { accountSize: 10000, riskPercent: 3, stopLoss: 50, pair: 'EUR/USD' },
};

Three mock files, 90 lines total. The upside is that changing one JSON object produces a different video without touching the composition code.

What is an action timeline in Remotion?

This is the part that replaces mouse clicks. I built a useActionTimeline hook that scripts UI interactions frame-by-frame:

// "At frame 150, start filling the account size field"
// "At frame 300, start filling the risk percentage"
// "At frame 450, start filling the stop loss"
const timeline = [
  { startFrame: 150, endFrame: 300, field: 'accountSize', from: 0, to: 10000 },
  { startFrame: 300, endFrame: 450, field: 'riskPercent', from: 0, to: 3 },
  { startFrame: 450, endFrame: 600, field: 'stopLoss', from: 0, to: 50 },
];

This is deterministic and reproducible. “At frame X, do Y” beats “click the input and hope the timing matches” every time. The hook is 65 lines and reusable across every composition.

How much setup does Remotion require?

Setup task Time Reusable?
Adapted 4 components 15 min Yes, across all videos
Created mock data (3 files) 10 min Yes, swap data for new videos
Built action timeline hook 15 min Yes, universal pattern
Remotion install + config 45 min Yes, one-time
Total ~85 min All reusable

The first video costs you. Every video after that is just a new composition file with different mock data and a different timeline. That’s the trade-off.

How do you build product demo videos with Remotion?

I built these three compositions for a forex position-size calculator app running on Next.js 15 with TypeScript and Tailwind CSS. Every composition reuses the same adapted components and mock data layer from the setup phase.

Video 1: Feature walkthrough (30 seconds)

This is the core demo. It shows a user filling in the calculator fields step-by-step, with animated highlights and a results card that fades in at the end.

The composition breaks down into frame-based phases:

const FeatureWalkthrough = () => {
  const frame = useCurrentFrame();

  // Phase 1: Title card (frames 0-150)
  const titleOpacity = interpolate(frame, [0, 60], [0, 1], {
    extrapolateRight: 'clamp',
  });

  // Phase 2: Account size fills (frames 150-300)
  const accountSize = interpolate(frame, [150, 300], [0, 10000], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
    easing: Easing.inOut(Easing.cubic),
  });

  // Phase 3: Results reveal (frames 600-750)
  const resultsOpacity = interpolate(frame, [600, 680], [0, 1], {
    extrapolateLeft: 'clamp',
    extrapolateRight: 'clamp',
  });

  return (
    <AbsoluteFill style={{ backgroundColor: '#0a0a0a' }}>
      <Sequence from={0} durationInFrames={150}>
        <TitleCard opacity={titleOpacity} />
      </Sequence>
      <Sequence from={150} durationInFrames={600}>
        <RemotionCalculator
          accountSize={Math.round(accountSize)}
          riskPercent={riskPercent}
          stopLoss={stopLoss}
          pair="EUR/USD"
        />
      </Sequence>
      <Sequence from={600} durationInFrames={300}>
        <RemotionResultsCard opacity={resultsOpacity} />
      </Sequence>
    </AbsoluteFill>
  );
};

The input values animate using Easing.inOut(Easing.cubic) for a natural feel. The results card fades in with a spring animation. Callout labels appear at strategic frames to guide the viewer’s attention. Total: 238 lines of code.

What was easier than expected: <Sequence> components handle timing so cleanly that I didn’t need to manually calculate frame ranges. You just say “start at frame 150, run for 600 frames” and nest your component inside.

What was harder than expected: Remotion’s bundler doesn’t recognize Next.js @/ path aliases. I had to change all imports to relative paths. Took 5 minutes, but felt like a gotcha that should be documented, or is it just me?.

Video 2: Changelog recap (45 seconds)

This composition reads five changelog entries from a mock data file and renders each as an animated card with staggered timing.



// The data drives the video. Change entries, get a different video
const changelogEntries = [
  { date: 'Jul 2, 2026', title: 'Add Risk Meter Visual', category: 'feature' },
  { date: 'Jun 28, 2026', title: 'Improve Mobile Responsiveness', category: 'improvement' },
  { date: 'Jun 20, 2026', title: 'Fix Exchange Rate Caching Bug', category: 'bugfix' },
  // ... 2 more entries
];

Each card slides in from the left with an opacity transition, staggered by 150 frames (5 seconds per entry). Category tags are color-coded: blue for features, green for improvements, orange for bug fixes. A title slide opens the video, and a “See you next month” slide closes it. 166 lines total.

The point of this composition isn’t technical complexity. It’s the workflow: update a JSON file with this month’s changes, run npx remotion render, and you have a changelog video monthly

Video 3: Bug fix before/after (30 seconds)

Side-by-side comparison. Left panel shows the “broken” version with input overflow on mobile viewports. Right panel shows the fixed version with proper responsive padding. Both animate in sync, same inputs, same timing, different layouts.

The synchronized animation is the part that no screen recording could produce without manual video editing. In Remotion, both sides use the same interpolate() calls with the same frame ranges, so they’re perfectly in sync by definition. 173 lines.

How do you render videos in Remotion?

npx remotion render remotion/index.ts feature-walkthrough output/feature-walkthrough.mp4
npx remotion render remotion/index.ts changelog-recap output/changelog-recap.mp4
npx remotion render remotion/index.ts bug-fix-comparison output/bug-fix-comparison.mp4

Total rendering time: 2 minutes 40 seconds for 120 seconds of video. Total file size: 7.6 MB.

How do AI coding agents work with Remotion?

In January 2026, Remotion launched Agent Skills, a set of 28 modular rule files that teach AI coding agents like Claude Code how to write correct Remotion code. The skill hit 150,000 installs on skills.sh within eight weeks, making it the most-installed skill not made by a platform company. The demo video got 6 million views on X within 48 hours.

The practical shift: instead of learning Remotion’s API from scratch, you describe what you want in plain English, and your AI agent writes the composition. The skill covers component patterns, transition types, animation primitives, and audio integration.

I tested this in a completely different project, my AI dev tool power rankings app. I installed Remotion, loaded the agent skills, and gave Claude Code a single prompt to generate a 25-second video with two sections: AI model rankings by WebDev Arena Elo, then a cross-fade transition into AI tool rankings. Both sections use real data from the June 2026 power rankings article.

The prompt was roughly this:

“Create a 25-second animated video for the June 2026 AI Dev Tool Power Rankings. Section 1: AI Model Rankings by Elo — Claude Opus 4.7 (1567), Qwen 3.7 Max (1541), Claude Opus 4.6 (1538), Claude Sonnet 4.6 (1523), GPT-5.5 (1505). Section 2: AI Tool Rankings — OpenCode #1, Cursor #2, Claude Code #3, Windsurf #4, Antigravity #5. Gold bar for #1, blue-gray for the rest. Staggered animations, cross-fade transition between sections, dark theme.”

Claude Code generated AiPowerRankings.tsx (207 lines) in about 7 minutes. It compiled and rendered without errors on the first pass. All 750 frames, zero fixes.

What makes this interesting is what Claude Code had to figure out on its own. The prompt didn’t specify font sizes, padding, bar height, transition duration, or how to handle independent animation timing across two sections. Claude Code chose 48px titles, 36px bar heights, 24px gaps, spring() with damping of 0.8 for the bar animations, and a 30-frame cross-fade using absolute positioning with opacity interpolation. It also built a reusable Section component that renders both halves of the video from different data arrays, so adding a third section (benchmarks, for example) would be one more component call.

What a human would tweak: transition speed (30 frames might be too slow or too fast depending on preference), bar height consistency if embedding alongside other videos, and whether the emoji movement indicators (🆕, ⬇️, ↔️) render cleanly at export resolution.

My honest take: For data-driven compositions with straightforward animations, AI generation is faster than writing by hand. 7 minutes from prompt to rendered MP4 with two animated sections and a cross-fade transition. But for complex multi-scene choreography or pixel-perfect brand compliance, you’d still want manual control. The real win is the monthly update cycle: when the July 2026 rankings drop, I change 10 lines of data in two arrays and re-render. The video stays current with the written article.



Is Remotion worth it for product demos?

How long does Remotion take to render videos?

Composition Duration Render time File size Lines of code
Feature Walkthrough 30s ~40s 1.5 MB 257
Changelog Recap 45s ~55s 3.8 MB 164
Bug Fix Comparison 30s ~40s 1.5 MB 199
AI Power Rankings 25s ~2.5 min 1.7 MB 207
Total 130s ~4 min 8.5 MB 827

Local rendering is free but uses your CPU. Remotion Lambda on AWS is faster but costs real money at scale.

How is Remotion licensed?

This matters, and most articles skip it. Remotion is not MIT licensed. The current terms:

  • Free for individuals and companies with three or fewer developers
  • $25/seat/month for companies with four or more developers (minimum $100/month)
  • Cloud rendering via Remotion Lambda is separate, pay-per-minute on AWS

Is Remotion faster than screen recording?

Video Remotion Screen recording Winner
First video ~35 min (setup + code + render) ~20 min (record, edit, export) Screen recording
Second video ~15 min (new composition + render) ~45 min (record, sync, edit) Remotion (3×)
Third video ~20 min ~30 min Remotion
Fifth video (data change only) ~10 min ~30 min (full re-record) Remotion (3×)

The ROI curve crosses after the second video. By the fifth, Remotion is consistently three times faster because you’re reusing components and compositions. The compounding advantage is that screen recordings become stale the moment your UI changes. Remotion videos are code; they stay current.

When should you use screen recording instead of Remotion?

Remotion replaces the videos you produce repeatedly, not the ones you capture once and throw away. Screen recording wins for one-off internal demos where polish doesn’t matter, user-testing sessions where you need real user interaction, anything involving live external services you can’t mock (OAuth flows, third-party integrations), and quick Loom-style walkthroughs for async team communication.

The question to ask: “Will I need to produce this video again?” If yes, Remotion. If no, screen recording.

What are the most common Remotion pitfalls?

  • Next.js path aliases break in Remotion’s bundler: Remotion’s webpack config doesn’t understand tsconfig.json path mapping. Fix: use relative imports in your Remotion components
  • Zod version mismatches: Remotion is strict about peer dependencies. If you get version errors, install the exact version Remotion requires (in my case, [email protected])
  • Config API changes between versions: The docs online may be ahead of your installed version. Config.setFramerate doesn’t exist in v4. Fix: use composition-level defaults and check your package.json version before copying from docs
  • Interpolate defaults to linear easing: Your animations will look robotic until you explicitly set easing curves. Always pass Easing.out(Easing.cubic) or similar. Linear is rarely the right choice for UI animations
  • Composition duration is not render time: A 30-second video (900 frames at 30fps) takes about 40 seconds to render, not 30. The extra time is encoding overhead. Don’t panic when the progress bar seems slow

Should you use Remotion for product demo videos?

Remotion turns video production into a frontend development task, but this is something that will help technical writers with frontend skills. The three demos I built- feature walkthrough, changelog recap, bug fix comparison, plus the AI-generated power rankings video- total 130 seconds of video from 827 lines of composition code. All four compositions rendered in under 4 minutes.

The setup cost is a bit too much: 85 minutes of component adaptation, mock data creation, and configuration before the first video exists. But that cost is amortized across every video you produce after that. By the second composition, you’re faster than screen recording. By the fifth, you’re three times faster. What’s your take on remotion? What do you think I may have missed out? I would love to hear from you.

Get set up with LogRocket’s modern React error tracking in minutes:

  1. Visit to get
    an app ID
  2. Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not
    server-side

    $ npm i --save logrocket 
    
    // Code:
    
    import LogRocket from 'logrocket'; 
    LogRocket.init('app/id');
                        

    // Add to your HTML:
    
    <script src="
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
                        

  3. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • NgRx middleware
    • Vuex plugin

Get started now

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

Last month I dived back into the foreign exchange market and noticed a little gap in how lot sizes are calculated and how slow that can be. To be sincere, as a developer, I didn’t even bother looking for an existing tool online, cause if it’s free, then there will be so many ads, and I’m not the biggest fan

Editor’s note: This JWT authentication tutorial was last updated on 23 July 2026 by Emmanuel John to discuss modern JWT authentication practices, including OAuth 2.0 and OIDC, secure token storage, refresh token rotation, XSS and CSRF risks, and scenarios where server-side sessions may be a better choice than JWTs.

In web development, authentication is one of the most complex aspects to implement yourself. Many web applications delegate authentication to third-party authentication services like Auth0 or rely on authentication built into the frameworks or tools they are built with.

This also means that many developers (maybe you too 🙂 ) don’t know how to build at least moderately secure authentication into their web applications. JWT provides an easy way to to do this

With knowledge of some of the security concerns to consider when using JWT, you can implement a more secure authentication as you see with third-party authentication services. So, in this guide, we’ll begin by covering what JWTs are, then we’ll go into how they’re used and why, and finally, we’ll go into the issues and concerns to look out for when using JWTs.

What is JWT?

JSON Web Token (JWT) is a standard for structuring data to be transmitted between two parties (commonly server and client). A JWT is a single string made up of two components, a JSON Object Signing and Encryption (JOSE) header and its claims (or payload), both base64url encoded and separated by a period (.).

This is the structure of a token:

(Header).(Payload)

Here’s an example of a token:

eyJhbGciOiJub25l4oCdfQ.ewogICJpZCI6ICIxMjM0NTY3ODkwIiwKICAibmFtZSI6ICJKb2huIERvZSIsCiAgImFnZSI6IDM2Cn0K

This token is constructed with these two components:

  • JOSE header:
    {
      "alg": "none"
    }
    // base64url encoded to: eyJhbGciOiJub25l4oCdfQ
    
  • Claims:
    {
      "id": "1234567890",
      "name": "John Doe",
      "age": 36
    }
    // base64url encoded to: ewogICJpZCI6ICIxMjM0NTY3ODkwIiwKICAibmFtZSI6ICJKb2huIERvZSIsCiAgImFnZSI6IDM2Cn0
    

The JOSE header contains details about the type of encryption, signing, or both applied to the token. "alg": "none” specifies that the token isn’t encrypted or signed.

Claims are the information that JWTs carry. In the context of user authentication and authorization, you can think of it as claims about a user. The claims in this token are made up of three fields id, name, and age.

JSON Web Tokens aren’t sent directly as JSON strings because they’re UTF-8 encoded. This means that they can contain characters that aren’t URL-safe (characters like “/” or “&” for example). They can’t be put safely in HTTP Authorization headers and URI query parameters.

To make tokens URL-safe, they’re encoded into base64url format. This allows them to be safely put in query parameters and authorization headers.

However, this form of JSON Web Tokens is unsecured because there’s no way of ensuring the integrity of its claims, making it very unsafe to use in user authentication.

How are JWTs used in authentication?

The type of JWTs used in handling user authentications are signed tokens (or JSON Web Signatures, JWSs). Signed tokens are essentially JWTs with a cryptographically generated signature, to ensure that the claims in the tokens haven’t been tampered with.

Three components go into making Signed tokens:

  • JOSE header — Information about the algorithm used to sign the JWT
  • Payload (claims) — A payload is a JSON Web Token that holds the data to carry
  • Signature — This is a string of characters created by hashing the payload and header (or just the payload) using the algorithm specified in the JOSE header. After generation, the signature is base64url encoded and added to the JWS

This is the structure of a signed token:

(Header).(Payload).(Signature)

Here’s an example of a signed JWT:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJhZ2UiOjM2fQ.4SkNQ2QZ8z5Lh7W0n2FK8KnXxXq_9yPmyMslK9YpN0A

The token is constructed from these components:

  • Header:
    {
      "typ": "JWT",
      "alg": "HS256"
    }

    Base64URL encoded as:

    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
  • Payload:
    {
      "id": "1234567890",
      "name": "John Doe",
      "age": 36
    }

    Base64URL encoded as:

    eyJpZCI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJhZ2UiOjM2fQ
  • Signature: Generated by applying HMAC SHA-256 to the Base64URL-encoded header and payload:
    eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjEyMzQ1Njc4OTAiLCJuYW1lIjoiSm9obiBEb2UiLCJhZ2UiOjM2fQ

    using the secret key your-256-bit-secret. The resulting signature is Base64URL encoded and appended as the third part of the JWT.

So how are signed tokens used in authentication? Here’s a simplified outline of the process:

  1. A user signs into their account on an authentication server
  2. The authentication server returns a signed token with their account information or an ID (or both)
  3. The signed token is stored in the browser’s localStorage or sessionStorage or anywhere the website prefers to store it
  4. The signed token is retrieved and used anytime a part of the website needs authenticated access

Here’s a visual representation of the process:

Diagram showing the JWT authentication process between the user's browser, authentication server, and web application.

Now that you know how JWTs work in authentication, let’s look at where they fit in the broader landscape of modern auth standards.

Where does JWT fit in OAuth 2.0 and OIDC?

JWTs are the token format. OAuth 2.0 and OpenID Connect (OIDC) are the protocols that define how those tokens are issued and used.

Many developers encounter JWTs first through OAuth 2.0 or OIDC flows, especially when integrating third-party identity providers like Google, GitHub, or Auth0. Understanding the distinction matters for implementing things correctly.

OAuth 2.0 is an authorization framework. It defines how a resource owner (a user) can grant a third-party client limited access to a protected resource (like an API) without exposing credentials. OAuth 2.0 itself does not mandate a token format, but JWTs have become the de facto standard for access tokens because they are self-contained and verifiable without a round-trip to the authorization server.

OpenID Connect (OIDC) is an identity layer built on top of OAuth 2.0. It introduces the ID token, which is always a JWT and contains claims about the authenticated user (like sub, email, name). OIDC is the protocol you are using when you click “Sign in with Google.”

Here is how they relate:

Concept Role Token type
OAuth 2.0 Authorization framework Access token (often a JWT)
OIDC Authentication layer on OAuth 2.0 ID token (always a JWT)
JWT Token format/standard Used by both

In practice, a typical OIDC flow issues three tokens:

  • ID token: A JWT asserting who the user is; intended for the client to read, not the API.
  • Access token: Used to call protected APIs; often a JWT but not required to be.
  • Refresh token: An opaque or JWT token used to obtain new access tokens; never sent to the API.

A common mistake is using the ID token to authorize API calls. The access token is what APIs should validate. The ID token is for the client application to establish user identity.

Why should you use JWTs?

It turns out that authentication isn’t easy to implement securely. I’ve made many web projects with simple hand-written authentication processes, where I just store the user’s identifier and password as plain JSON strings in JavaScript localStorage and pass them to any region of my application that needs authenticated access.

Fortunately, those projects didn’t have many users (or any in most cases), so it wasn’t rewarding to exploit. If the web applications had many (and important) users and had authentication implemented this way, it would’ve meant disaster.

Signed tokens prevent these kinds of disasters by:

  • Removing the need to store passwords in localStorage: A session ID in a signed token is enough to identify users. If the signature is generated using the HMAC SHA-256 algorithm, and the key used to create the signature is kept with extreme secrecy, and as random as possible, you can rest assured that only the authentication server can produce and verify the signature (provided that an attacker doesn’t have access to a quantum computer, and know how to use it)
  • Removing the need for redundant database querying: If claims about a user can be stored in a JWT and the integrity of the claims can be assured with the signature in a JWS, an API can use those claims without raising any concerns

But JWTs aren’t perfect solutions for secure authentication. They still have issues and concerns to look out for (and possibly work around) when using them in your project.

Where should you store JWTs?

You should store access tokens in memory and refresh tokens in HttpOnly, Secure, SameSite=Strict cookies.

Token storage is one of the most debated topics in JWT security, and the answer depends on which threats you are prioritizing. Every storage option comes with trade-offs.

Here is a comparison of storage options:

Storage location Accessible by JS Sent automatically XSS risk CSRF risk
localStorage Yes No High None
sessionStorage Yes No High None
In-memory (JS variable) Yes (same tab only) No Medium None
HttpOnly cookie No Yes (same-origin) None Medium
HttpOnly + SameSite=Strict cookie No Yes (strict same-origin) None Low

Both localStorage and sessionStorage are accessible via JavaScript on the page. A successful XSS attack gives an attacker full access to the token immediately. window.localStorage.getItem('token') is all it takes. Avoid storing JWTs with meaningful access scope here.

Storing access tokens in-memory means they disappear on page refresh and are not accessible from other tabs or persisted to disk. This is the most XSS-resistant client-side option for access tokens, though it requires a separate mechanism (like a refresh token in a cookie) to restore a session after a page reload.

With HttpOnly cookies, the browser sends these automatically with every matching request, and they cannot be read by JavaScript at all. This eliminates XSS token theft but introduces CSRF risk. You can mitigate CSRF with SameSite=Strict and CSRF tokens.

How do refresh tokens and token expiration work?

Access tokens should be short-lived (5 to 15 minutes). Refresh tokens should be rotated on every use and revocable server-side.

One structural weakness of JWTs is that they are stateless by default. Once issued, a server cannot invalidate a token before its expiration unless it maintains a server-side blocklist, which reintroduces statefulness.

Token expiration and refresh token rotation are the primary tools for managing this problem.

What is access token expiration?

The exp claim defines when a token expires. Keep access token lifetimes short — 5 to 15 minutes is a common range for high-security applications, with 1 hour being a reasonable upper limit for most apps.

{
  "sub": "user_123",
  "iat": 1720652400,
  "exp": 1720653300,
  "roles": ["user"]
}

A short-lived token limits the damage window if one is stolen. An attacker with a captured token has minutes, not days, before it becomes useless.

What is refresh token rotation?

Refresh tokens are long-lived credentials (days to weeks) used to obtain new access tokens without prompting the user to re-authenticate. Because they are long-lived, they need stricter protection.

Refresh token rotation means issuing a new refresh token every time the old one is used. The old token is immediately invalidated. This means:

  • If a refresh token is stolen and used by an attacker, the legitimate user’s next refresh request will fail (their token was invalidated by the attacker’s prior use).
  • The server can detect reuse of an already-rotated token, which signals a potential compromise.

XSS vs. CSRF: How does your storage choice affect your attack surface?

localStorage gives you XSS risk. Cookies give you CSRF risk. Neither is inherently safer, so the question is which risk you can better mitigate given your architecture.

What is XSS (Cross-Site Scripting)?

XSS occurs when an attacker injects malicious JavaScript into a page that runs in another user’s browser. If your token is in localStorage or sessionStorage, that script can read it directly:

// What an attacker's injected script does
fetch(' + localStorage.getItem("access_token'));

Mitigations for XSS:

  • Use a strong Content Security Policy (CSP) to restrict script sources.
  • Sanitize all user-generated content before rendering.
  • Store tokens in memory or HttpOnly cookies instead of localStorage.
  • Keep third-party JavaScript dependencies minimal and audited.

What is CSRF (Cross-Site Request Forgery)?

CSRF occurs when an attacker tricks a logged-in user’s browser into making a request to your application without the user’s intent. Because cookies are sent automatically by the browser, a forged request from a malicious site to your API will include the victim’s cookies, including any JWT stored there.

Mitigations for CSRF:

  • Use SameSite=Strict or SameSite=Lax on cookies (the most effective modern defense).
  • Implement CSRF tokens (the double-submit cookie or synchronizer token patterns).
  • Validate the Origin and Referer headers on state-changing requests.
  • Avoid SameSite=None unless you explicitly need cross-site cookie sending.

What are the limitations of JWTs?

JWTs like many other tools in the world, aren’t perfect. They’re good for user authentication, but not without shortcomings. In this section, I’ll address some popular concerns.

So let’s start with the first concern.

Are JWTs encrypted?

Signed tokens provide the benefit of verifying the integrity of the claims in the tokens. This allows them to be useful for authentication purposes. This doesn’t mean that the claims stored in the tokens aren’t hidden.

If your web application needs to store sensitive information in tokens, the website needs to handle them with caution. Generally, you should avoid storing sensitive information in tokens because it is very difficult to protect them against all possible cybersecurity attacks.

In cases where a web application needs to store sensitive information in tokens, encrypted forms of JWTs exist for this reason.

Do JWTs require JavaScript?

Compared to the internet of the early 2000s modern-day internet is more secure. But, on its own, the modern-day internet still isn’t a hundred percent secure. Anything that JavaScript has access to can still potentially be exploited.

Because of the structure of modern applications, it has become more important for JavaScript to have access to the tokens to, for example, send requests to APIs. However, web applications have reasons for their structure, and in some cases, JavaScript having access to the tokens is unavoidable. Fortunately, the internet has gotten secure enough for access to JavaScript to be less of a concern than it was in the earlier internet.

There isn’t a good solution to this concern. Regardless of where you store tokens, you’re opening the tokens to at least one form of exploit. Storing in cookies or sessions is open to CSRF (Cross-Site Request Forgery) attacks, and storing anywhere JavaScript can access is open to XSS (Cross-Site Scripting) attacks.

Are JWTs subject to size limits?

Depending on how you store and transmit JWTs, they’re subject to size constraints imposed by browsers. For example, all browsers impose a 4 KB and 5 MB limit on the total amount of data that a web application can store in cookies and JavaScript localStorage respectively.

If your web application uses significant portions of these storage mechanisms (although unlikely), you can use session tokens instead. They’re smaller, but they can’t have payloads, with extra pieces of information, like with JWTs.

When should you not use JWTs?

The short answer to this question is when you need immediate revocation, when your clients are only browsers talking to a single backend, or when the complexity does not pay off.

JWTs vs. server-side sessions: Which should you choose?

JWTs are not the default correct answer for every authentication problem. Here are cases where traditional server-side sessions are a better fit:

Concern JWT Server-side session
Scalability (stateless) Excellent (no DB lookup per request) Requires session store (Redis, DB)
Revocation Hard (requires a blocklist) Trivial (delete the session record)
Token size Can grow large with many claims Tiny (just a session ID)
Cross-service auth Strong fit (verifiable without shared DB) Harder (requires shared session store or sticky sessions)
Implementation complexity Higher (needs refresh logic, rotation, storage strategy) Lower (most frameworks handle it out of the box)
Suitable for mobile/API clients Yes Often awkward (cookie-based by default)

When are server-side sessions the better choice?

  • You have a traditional server-rendered web app (Rails, Django, Laravel, Next.js with server actions). These frameworks have mature, battle-tested session handling built in. Adding JWT on top adds complexity without obvious benefit.
  • You need to revoke sessions immediately. Logging a user out of all devices, responding to a compromised account, or enforcing role changes mid-session all require instant revocation. JWTs cannot do this without a blocklist.
  • Your auth surface is a single backend. JWTs shine when multiple services need to verify the same token. If only one server ever reads the token, sessions are simpler.
  • Your team is not familiar with JWT pitfalls. The alg: none attack, weak secrets, missing expiration claims, and improper storage have all caused real breaches. If you are not going to implement JWTs carefully, sessions are safer by default.

When are JWTs the right choice?

  • Microservices and distributed architectures where multiple APIs need to verify identity without a shared session store.
  • Mobile applications and public APIs where stateless, bearer-token authentication is the standard expectation.
  • Third-party integrations where you need to issue scoped, time-limited credentials to external services.
  • OAuth 2.0 and OIDC flows where the token format is defined by the protocol.

Frequently Asked Questions

Can I decode a JWT without the secret key?

Yes, the header and payload are only base64url encoded, not encrypted. Anyone can decode them. The signature requires the secret key to verify, but the payload is readable by anyone who has the token. This is why you should never store sensitive data in JWT payloads.

What happens when a JWT expires?

The server rejects it with a 401 Unauthorized response. The client should then attempt a silent refresh using its refresh token. If the refresh token is also expired or invalid, the user must re-authenticate.

Should I validate JWTs on every request?

Yes, always. Signature validation is computationally cheap (especially with RS256 and cached public keys via JWKS). Skipping verification because “we trust the client” defeats the purpose of signing entirely.

Can I use the same JWT for both authentication and authorization?

Yes, and most applications do. The JWT can carry both identity claims (sub, email) and authorization claims (roles, permissions). The key constraint is that embedded claims are static until a new token is issued. If a user’s role changes mid-session, the access token will not reflect that until it expires and is refreshed.

Key Takeaways

JWTs are useful tools in user authorization and authentication, but they’re just standards. They’re not built directly into programming languages or many frameworks. Using them in many cases is based on how you (or the library you choose to generate and handle them) implement JWTs. If you want to learn how to implement them, you can check out our guide on implementing JWT authentication with Vue and Node.js.

For most production applications, the practical path is: short-lived JWTs with RS256 signing, refresh token rotation in HttpOnly cookies, and a clear revocation strategy that matches your risk tolerance.

The post JWT authentication: Best practices and when to use it appeared first on LogRocket Blog.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

Editor’s note: This JWT authentication tutorial was last updated on 23 July 2026 by Emmanuel John to discuss modern JWT authentication practices, including OAuth 2.0 and OIDC, secure token storage, refresh token rotation, XSS and CSRF risks, and scenarios where server-side sessions may be a better choice than JWTs. In web development, authentication is one of the most complex aspects

How to clean up AI-generated code with Fallow

Learn how to use Fallow to analyze AI-generated code, detect dead code, duplicate logic, and complexity issues, and integrate automated code quality checks into your AI-assisted development workflow.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

How to clean up AI-generated code with Fallow Learn how to use Fallow to analyze AI-generated code, detect dead code, duplicate logic, and complexity issues, and integrate automated code quality checks into your AI-assisted development workflow. PakarPBN A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to

Every time you explain your team’s coding standards to Claude, you are doing work that should be reusable. The same thing happens when you re-explain how to scaffold components, review pull requests, format commit messages, or avoid JavaScript-heavy solutions for problems CSS already solves.

Claude skills help solve that repetition problem. A skill is a reusable instruction set that Claude Code can load when a task matches the skill’s description. Instead of pasting the same prompt into every session, you can save the process once in a SKILL.md file and let Claude apply it when it is relevant.

For React teams, this matters because most AI coding failures are not syntax failures. They are convention failures: the component compiles, but it lands in the wrong folder, uses the wrong design tokens, skips the wrong test, or applies the wrong architectural pattern. Skills turn those recurring preferences into project-level guardrails.

In this article, we’ll look at five Claude skills that can make React development more consistent: planning, project memory, component scaffolding, PR review, and CSS-first architecture. We’ll also look at a few skills that sounded useful but were not worth keeping.

What Claude skills are

Claude skills are Markdown-based instruction files that extend Claude Code for a specific task or workflow. Anthropic’s docs describe skills as SKILL.md files with instructions that Claude adds to its toolkit. Claude can invoke a skill automatically when it matches the task, or you can invoke one directly with a slash command such as /review-pr or /scaffold-component.

Skills are useful when you keep pasting the same checklist, convention, or multi-step process into chat. They are especially useful for teams because project skills can live in .claude/skills/ at the root of a repo, which makes them shareable through source control.

A simple skill looks like this:

---
name: scaffold-component
description: >
  ALWAYS invoke when the user asks to create, scaffold, or
  generate a React component.
---

The description is not decorative. It is one of the main ways Claude decides whether the skill should activate. If the description is vague, the skill may not fire when you need it, or it may fire too often.

This is why skills are different from one-off prompting. A normal prompt helps with one task. A skill defines a repeatable workflow that Claude can apply across many tasks. If you are already experimenting with AI coding tools, LogRocket’s overview of AI code generation is a useful baseline for understanding where skills fit into the broader AI-assisted development workflow.

How Claude Code uses skills

Claude does not need to load every skill body into context at once. Instead, Claude Code uses the skill’s metadata to decide whether the skill is relevant. When it is, Claude can load the skill body and follow its instructions.

That distinction matters. If you put every team convention into one giant instruction file, you pay a context cost on every request. A better pattern is to make each skill small and procedural, then point it to supporting files when the task needs deeper reference material.

For example, a React component scaffolding skill might contain the steps Claude should follow, while a neighboring REFERENCE.md file contains design-token mappings, folder examples, and naming conventions. The skill tells Claude when to load the reference file instead of dumping the whole reference into every task.

Anthropic recommends keeping SKILL.md focused and moving detailed reference material into supporting files. Its docs also note that the description and when_to_use text are truncated in the skill listing, so the first sentence should state the most important trigger clearly.

1. Interview-first planning

The most useful skill in my React workflow is also one of the shortest. It prevents Claude from jumping directly from “build this feature” to “here are three new files.”



Without a planning skill, Claude can be fast, confident, and subtly wrong. It may build a component that works, but with assumptions you never approved: the wrong empty state, the wrong debounce behavior, or the wrong ownership boundary between client and server code.

The fix is to make Claude interview you before it plans.

---
name: plan-with-me
description: >
  ALWAYS invoke when the user describes a new feature, page,
  or significant change. Do not write code or produce a plan
  without this skill. Use when the user says "build", "create",
  "add", "implement", or describes any non-trivial task.
---

## Steps
1. Interview me relentlessly about every aspect of this task.
   Walk down each branch of the design tree, resolving
   dependencies between decisions one by one.
   If a question can be answered by exploring the codebase,
   explore the codebase instead of asking me.
   For each question, provide your recommended answer.

2. Once we reach shared understanding, produce a plan:
   - Summary of what we agreed on
   - Task breakdown with file paths
   - Blocking relationships between tasks
   - Open questions we deliberately deferred

3. Wait for my approval before writing any code.

The important part is not that Claude asks questions. It is that the skill makes questioning part of the workflow instead of a courtesy step Claude may skip.

In one dashboard search feature, this skill forced Claude to ask about debounce timing, empty states, index updates, and server/client boundaries before generating code. Those questions surfaced decisions that would have become review comments later.

This pattern works well with Claude Code because Claude can inspect the codebase when the answer is discoverable. If the question is “Where do search components usually live?” Claude should look. If the question is “Should empty search results show recent searches or suggestions?” Claude should ask.

The result is a plan that becomes a lightweight spec for the rest of the session. Claude can reference the agreed decisions while building, and you can reject the plan before code exists.

2. Project memory

Project memory is the skill that keeps the other skills accurate. Every other skill in this article reads from reference material. This one updates that reference material when the project changes.

The problem is simple: your reference file says UserProfile lives in src/features/user/, but the component moved three weeks ago. Now your scaffolding skill writes to a dead directory. Your PR review skill checks against an outdated convention. Your architecture skill reasons from stale structure.

A project memory skill maintains a current project index, such as PROJECT-STATE.md, and updates only the parts that changed.


More great articles from LogRocket:


---
name: update-project-memory
description: >
  ALWAYS invoke after completing any task that adds, removes,
  renames, or relocates files, components, routes, API endpoints,
  dependencies, or design tokens. Also invoke when project
  conventions change. Do not skip this after structural changes.
---

## What to maintain
- .claude/skills/PROJECT-STATE.md

## On every update:
1. Read the current PROJECT-STATE.md
2. Diff what changed against what is documented
3. Update ONLY the sections that changed:
   - Components: name, path, client/server, purpose (one line)
   - Routes: path, page component, layout
   - API endpoints: path, method, what it does
   - Dependencies: package, why it is here, version
   - Design tokens: new/removed tokens in Tailwind config
   - Conventions: any pattern that changed
4. Timestamp the update
5. Do NOT rewrite sections that did not change
6. Keep each entry to one line. This is an index, not documentation

The “one line” rule is doing real work. Without it, Claude tends to turn the project index into full documentation. That sounds helpful until the file becomes too long to scan and too expensive to keep current.

The goal is not to create a wiki. It is to create a live table of contents for the codebase.

Once this exists, other skills can read from PROJECT-STATE.md before acting. The component scaffolding skill can check current folder structure. The PR review skill can compare diffs against current conventions. The API pattern skill can see which endpoints already exist.

This also creates a useful handoff artifact. A technical writer or onboarding engineer can expand the index into documentation without reverse-engineering the repo from scratch. For teams thinking about AI-readable documentation more broadly, this connects closely to the ideas in LogRocket’s article on recreating Claude Skills in GitHub Copilot, which frames skills as a way to package domain knowledge for AI tools.

3. Component scaffolding

Claude can generate clean React components. The problem is that it does not generate them consistently unless you define your conventions clearly.

A component scaffolding skill encodes your project’s component architecture once: where files go, how props are typed, when to use Server Components, when to add tests, and which design tokens are allowed.

---
name: scaffold-component
description: >
  ALWAYS invoke when the user asks to create, scaffold, or
  generate a React component. Do not create components
  directly without this skill.
disable-model-invocation: true
argument-hint: "[ComponentName]"
---

## Steps
1. Read REFERENCE.md for naming conventions and directory map
2. Create directory: src/features/[feature]/components/[ComponentName]/
3. Generate:
   - [ComponentName].tsx — typed props interface, functional component
   - [ComponentName].test.tsx — describe block + placeholder test
   - index.ts — barrel export
4. Default to Server Components. Add 'use client' ONLY if
   useState, useEffect, or event handlers are required
5. Use Tailwind classes from design tokens in REFERENCE.md.
   Do not use arbitrary values
6. Run tsc --noEmit to verify compilation
7. Report: files created, props interface, client/server decision + reason

This skill should stay procedural. Put the rules in REFERENCE.md: naming rules, directory examples, design-token mappings, and examples of existing components that follow the convention.

That separation matters. When process steps and reference material live in the same file, Claude may cherry-pick. It follows some instructions, skips others, and still produces something plausible. Keeping SKILL.md as the router and REFERENCE.md as the reference file makes the workflow easier to maintain.

The disable-model-invocation: true field is also worth considering. In this case, scaffolding creates files, so you may want to invoke it manually rather than letting Claude infer when to run it.

For React teams, the biggest win is not that Claude writes the component. It is that Claude writes the component the way the codebase expects. That includes folder structure, test placement, prop typing, export style, and client/server reasoning.

4. PR review

A PR review skill is useful because most review feedback is repetitive. Naming, structure, error handling, type safety, and unnecessary re-renders all come up again and again.

A one-off “review this PR” prompt usually produces generic feedback. A skill can force Claude to review against the project’s actual conventions and return feedback in a format that is easy to act on.

---
name: review-pr
description: >
  ALWAYS invoke when the user asks to review code, review a PR,
  check a diff, or asks "what do you think of this code".
  Do not provide code review feedback without this skill.
---

## Steps
1. Read CONVENTIONS.md for project-specific patterns
2. Check the diff against these categories:
   - Naming: components PascalCase, hooks use*, utilities camelCase
   - Structure: no prop drilling past 2 levels, no barrel export cycles
   - Error handling: async operations wrapped, error boundaries present
   - Types: no `any`, no type assertions without comment explaining why
   - Performance: no unnecessary re-renders, memo only when measured
3. For each finding:
   - File and line
   - What is wrong (one sentence)
   - Suggested fix (code, not prose)
4. Severity: must fix | should fix | nit
5. If nothing found in a category, skip it. Do not pad the review.

The last line is the difference between a helpful review and a noisy one. If you ask Claude to review every category, it may invent weak comments just to satisfy the checklist. Telling it to skip empty categories reduces padding.

A good PR review skill should also separate correctness from style. Bugs and broken assumptions should appear before naming or formatting comments. Otherwise, serious issues get buried under low-stakes suggestions.

For larger teams, this skill works best as a pre-review step rather than a replacement for human review. Claude can catch repeatable issues early, and reviewers can spend more time on product behavior, architecture, and tradeoffs. LogRocket’s guide to leveling up Claude Code covers adjacent workflow improvements, including hooks and commands that can make AI review more constrained and repeatable.

5. CSS-first architecture

The CSS-first skill started as a refactoring helper. Its original job was to find JavaScript used for layout, responsiveness, or visual state and replace it with native CSS where possible.

That was useful but too narrow. The skill only fired during refactors, which meant Claude still reached for JavaScript while building new components. The better version makes CSS-first thinking the default for visual behavior.

---
name: css-first
description: >
  ALWAYS invoke when the user asks to style a component, handle
  responsive layout, add animations, or implement any visual behavior.
  Also invoke when reviewing components that use JS for layout concerns.
  Do not write layout/animation/responsive JS without this skill.
---

## CSS-first rules
- container queries over JS/resize-observer breakpoints
- scroll-driven animations over JS scroll listeners
- content-visibility: auto over JS virtualization for lists under 10,000 items
- :has() selector over JS parent-state toggling
- Tailwind classes from design tokens only; no arbitrary values
- Logical properties (margin-inline, padding-block) over physical ones

## Steps
1. Read the component requirements
2. For each visual behavior, check if CSS handles it natively
3. Only reach for JS when CSS genuinely cannot handle the behavior:
   - Drag-and-drop
   - Complex gesture handling
   - Canvas/WebGL rendering
   - Lists exceeding 10,000 items
4. For each CSS solution, include browser support notes
5. Output as component code with styles
6. If reviewing existing code, output as a unified diff

This kind of skill is valuable because AI coding assistants tend to overuse the tools they know are broadly available. For visual behavior, that often means more state, more event listeners, and more effects than the component actually needs.

A CSS-first skill forces Claude to check native platform capabilities before adding JavaScript. That does not mean JavaScript is wrong. It means JavaScript should be a deliberate choice, not the default answer for every layout or interaction problem.

This skill pairs naturally with LogRocket’s argument to stop using JavaScript to solve CSS problems. If that article is the principle, this skill is the operational version Claude can apply while writing components.

Skills I deleted

Not every skill earns its keep. The skills I removed fell into three categories: skills that duplicated what Claude already does well, skills that did not run often enough to justify the maintenance cost, and skills where the output looked confident but carried too much risk.

Deleted skill Why I removed it Better replacement
Prop documentation Claude can usually infer decent prop docs from TypeScript interfaces without a dedicated skill Ask for docs only when publishing or onboarding requires them
Storybook story generation The stories compiled, but they rarely captured interesting states or realistic interactions Provide explicit story states in the prompt or maintain a Storybook reference file
Accessibility audit Useful, but periodic rather than daily Run as a manual review workflow with axe-core and human checks
Bundle analysis The trigger description was too vague and activation was unreliable Move it to a shell script or CI workflow
Class-to-hooks migration The code compiled, but subtle lifecycle behavior changed Treat migrations as human-led refactors with AI assistance

The migration skill was the clearest example of confidence becoming dangerous. Claude could convert lifecycle methods into useEffect calls that looked right, passed lint, and still changed behavior. Stale closures, missing cleanup, and effect timing problems are easy to miss until QA or production exposes them.

Test generation had a similar failure mode at first. Claude’s default tests often assert on implementation details, pass on day one, and break during harmless refactors. That skill became useful only after adding strict rules: test behavior, include failure cases, avoid implementation details, and describe coverage gaps.

The lesson is that skills should encode repeatable judgment. If the task requires too much contextual discretion, a skill may create false confidence instead of quality.

Build Claude skills for yourself first

Start with the task you repeat most often. Do not start by installing a large collection of community skills or turning every preference into a new workflow.

The best first skill is usually boring:

  • Ask me questions before planning a feature
  • Scaffold components using our folder structure
  • Review PRs against our conventions
  • Update project memory after structural changes
  • Prefer CSS before adding JavaScript for visual behavior

Specific skills outperform generic ones. A skill for “better React code” is vague. A skill for “scaffold a dashboard filter component using our route structure, design tokens, and server/client conventions” gives Claude something concrete to execute.

If you are building a search page, store the search behavior, indexing assumptions, empty states, and component structure as project reference material:

Example design architecture reference for a Claude skill

If you are building an ecommerce checkout, the checkout flow conventions should become reference material. If you are building an analytics dashboard, chart states, loading states, permission rules, and data-fetching patterns should be documented somewhere Claude can read them.

The more specific the skill, the better the output.

Conclusion

Claude skills are most useful when they capture the repeated parts of your development workflow: planning, scaffolding, review, memory, and architectural preferences. They do not make Claude a perfect engineer, but they do make its output more consistent.

For React teams, that consistency is the real value. A good skill does not just tell Claude what to write. It tells Claude how your team thinks about components, boundaries, state, styles, tests, and review quality.

Start with one skill. Keep it short. Test it for a week. Then refine the description, supporting files, and activation rules based on where Claude gets confused. The boring skills compound because they remove the same friction from every session after that.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

Every time you explain your team’s coding standards to Claude, you are doing work that should be reusable. The same thing happens when you re-explain how to scaffold components, review pull requests, format commit messages, or avoid JavaScript-heavy solutions for problems CSS already solves. Claude skills help solve that repetition problem. A skill is a reusable instruction set that Claude