DEV Community

Fernando Paladini
Fernando Paladini

Posted on

Build a Test-Gated Manifest V3 Extension for Safe X Tab Automation

Automating actions in a social timeline is easy to start and surprisingly hard to bound. A browser extension can click the wrong control, run while you are away from the tab, request more permissions than it needs, or hide its failure mode behind a vague counter.

This tutorial uses X Likes Automator, a small open-source Manifest V3 extension, to show a more reviewable path. You will install the stable v1.1.0 release, inspect the permission boundary, run the repository's 171-test suite, and configure a deliberately conservative first session.

The goal is not to promise safe or compliant automation. The project warns that automated likes can conflict with X rules and may lead to rate limits, restrictions, or suspension. Treat the extension as an educational, personal-use example and stop if X shows an automation warning.

What you will build

You will load an unpacked browser extension into a Chromium browser and use it only in an X tab where you are already signed in. The extension reads visible posts, selects an eligible Like control, and pauses when the tab or window is not active.

The important design choice is the narrow surface: the extension is not a login client and does not use an X API token. Its manifest requests storage plus host access for https://x.com/* and https://twitter.com/*. The repository's security tests also assert that cookies, passwords, session tokens, and unrelated sites are not collected.

Prerequisites

  • Chrome, Brave, or Microsoft Edge with Manifest V3 support.
  • A normal browser tab already open at X, with an account you control already signed in.
  • Node.js 20 or newer if you want to run the tests. Node is not required to run the unpacked extension.
  • A clone or the official v1.1.0 release archive.

Do not paste credentials into the repository or into the extension. Do not use a browser profile that contains accounts you are not authorized to operate.

1. Verify the release locally

Clone the exact stable tag instead of relying on the moving default branch:

git clone --branch v1.1.0 --depth 1 https://github.com/paladini/x-likes-automator.git
cd x-likes-automator
Enter fullscreen mode Exit fullscreen mode

The tag is the reproducibility anchor for this tutorial. The README and release page identify v1.1.0, while the license file identifies the project as MIT.

Run the included checks:

npm test
Enter fullscreen mode Exit fullscreen mode

The release currently reports 171 passing tests covering the manifest, permissions, settings, visible-page behavior, pause and resume rules, refusal list, localization, documentation, and policy engine. A green run does not prove that X accepts automated activity. It only checks the tagged project behavior.

2. Load the extension without a build step

Open the extensions page for your browser. In Chrome, the documented address is chrome://extensions; the equivalent pages are brave://extensions and edge://extensions.

  1. Enable Developer mode.
  2. Click Load unpacked.
  3. Select the cloned x-likes-automator directory.
  4. Confirm that the selected directory contains manifest.json at its top level.

The repository deliberately has no bundling step. Loading the source directory makes the reviewed JavaScript, manifest, popup, icons, and tests visible. If the browser reports a manifest error, stop and inspect the selected directory instead of downloading a random replacement archive.

Pin X Likes Automator in the browser toolbar, then open https://x.com/home in a regular tab. The extension does not open a new window or perform a login flow.

3. Configure a conservative first session

The popup is localized in Brazilian Portuguese. The setting names below are the behavior documented by the release:

Setting v1.1.0 behavior
Interval Integer from 1 to 60 seconds; default 5 seconds
Interval jitter A 5-second setting chooses a delay from 4.25 to 5 seconds
Optional cap 1 to 1,000,000 when enabled; default stored cap is 100
Original post in a reply thread Enabled by default
Plain repost Enabled by default, but can be turned off

For a first review, set the interval to 60 seconds, enable a cap such as 5, and turn off Repostar também. This keeps the session focused on the Like path and gives you a short, observable run. The cap is a control for your account activity, not a guarantee of compliance.

Press Iniciar while the active tab is an X home timeline, profile, search result, or single-post thread. If the active tab is another site, the project refuses to start.

4. Observe the policy boundary

The extension separates decisions from DOM operations. lib/policy.js is a pure decision engine that validates settings, classifies the current X surface, chooses the next eligible post, and decides whether to like, scroll, wait, pause, or stop. content/content.js adapts those decisions to the page.

That separation gives you useful review points. The extension should pause when the document is hidden or the window loses focus. It should skip a post that is already liked, remember a post within the current session, and refuse unsupported pages such as messages, settings, notifications, and compose screens.

The project also keeps an explicit refusal list. It does not click reply, quote, follow, direct message, login, or cookie controls. When the optional repost behavior is enabled, it only targets the plain repost menu item and never opens a composer.

If X displays an unusual-activity notice, the documented behavior is to wait 60 seconds and resume. The extension does not attempt to bypass that protection. You should still stop the session if the notice repeats or if the account's activity looks unexpected.

5. Verify the result and stop cleanly

During a small capped run, check the popup counter against the visible page. Switch away from the X tab and confirm that the status changes to paused. Return to the tab and confirm that the same session count resumes. Then click Parar before investigating anything else.

The repository documents a five-minute page reload cycle that preserves the session count through browser storage. A browser restart clears the volatile run state, so starting again requires an explicit button press. These details matter because a persistent background worker would have a different risk profile.

After stopping, inspect the browser's extension details and the repository's manifest.json. The expected permission shape is small:

{
  "permissions": ["storage"],
  "host_permissions": ["https://x.com/*", "https://twitter.com/*"]
}
Enter fullscreen mode Exit fullscreen mode

This snippet is a review aid, not a complete manifest. Compare it with the actual release file rather than replacing the file with a hand-written version.

Failure modes worth checking

The popup says the tab is unsupported. Navigate to the X home timeline, a profile, a search result, or a thread. The extension intentionally ignores messages, notifications, settings, explore, compose, and non-X pages.

The session stays paused. Make the X tab visible and focus the browser window. The pause is presence-based by design.

The session does not start after installation. Reload the X tab and press Iniciar again. A tab that existed before installation may not yet have the content script.

The browser shows an automation warning. Do not increase the rate or try to evade the warning. Stop the session, review the account impact, and consult X's current rules.

The test suite fails. Do not treat a partial result as release validation. Check the Node version, rerun npm test from the tagged checkout, and compare the local files with the official release.

Security and privacy boundaries

The extension's narrow permissions reduce exposure, but they do not remove the central risk: it acts on a signed-in social account. The project cannot guarantee that a selector will remain correct as X changes its interface, and it cannot guarantee that automated activity is allowed for your account.

Review the security policy before reporting a vulnerability. Keep the account logged in only in a profile you control, use a small cap, keep the interval conservative, and remove the unpacked extension when you finish evaluating it.

FAQ

Does it need an X API key?

No. The documented design uses the open X tab and does not request an API token or credentials.

Does it run on every website?

No. The manifest host permissions and content-script matches are limited to X and Twitter origins.

Is a passing test suite a safety guarantee?

No. It verifies repository behavior at the checked-out release. It cannot predict policy enforcement, account restrictions, or future changes to X's DOM.

Can I make it run unattended?

The project is designed around an active, visible tab and pauses when the tab is inactive. Do not treat its reload behavior as permission to leave account automation unattended.

Takeaway

The useful lesson in X Likes Automator is not that social activity can be automated. It is that a browser extension becomes easier to review when its release is pinned, permissions are explicit, decisions are tested, unsupported actions are refused, and stopping behavior is visible.

If you try the tagged release, keep the first session small and verify each state transition yourself. Which boundary would you want to see tested before trusting a browser extension that acts on a signed-in account?

Disclosure: AI assistance was used to organize and edit this tutorial. The repository behavior, release metadata, documentation, license, configuration, and test result described here were checked against the public v1.1.0 sources.

Top comments (0)