Skip to content

v0.2.0

Released 2 July 2026. This release follows a full audit of the check engine. The theme is honesty: checks that could not actually verify a condition no longer pretend they did, and results that were wrong in common real-world setups are now correct.

Install or update:

Terminal window
npx orino-cli@latest audit
  • New exit code 2 — when no supported framework is detected and no URL is provided, Orino now exits with code 2 in every output mode. Previously, --json and --quiet runs silently reported a meaningless 100/100 score with exit code 0, giving CI pipelines a green light on projects Orino never analysed.
  • nextjs-csr-page downgraded from critical to warning — the check fired on every 'use client' page with a message claiming the page “renders on the client only”. Client components in the App Router are still server-rendered; the real costs are the inability to export metadata and effect-fetched content being absent from the initial HTML. The message now says exactly that.

Framework detection

  • JavaScript-only Next.js projects (pages/index.js, app/layout.js) are now detected. Previously only .tsx/.jsx files were probed, so plain-JS codebases were reported as “unknown”.

False positives eliminated

  • camelCase dynamic route params ([productId]) are no longer flagged as “uppercase in URL” — parameter placeholders are excluded from the URL convention check.
  • next/image with the fill prop no longer triggers “missing width/height” — fill-mode images size from their container.
  • Sitemap indexes (the default output of next-sitemap) are now recursed into. Previously child sitemaps were treated as pages, producing bogus “orphan page” and “not linked from homepage” warnings on the most common Next.js sitemap setup.
  • JSON-LD nested under @graph (the format Yoast and most WordPress SEO plugins emit) is now unpacked, and @type arrays are handled. Sites using these formats were falsely told their Organization schema was missing.
  • Astro layouts that wrap another layout are no longer flagged for missing <title>/description/og:image they legitimately delegate.
  • Servers that reject HEAD requests (405/501) are retried with GET before sitemap URLs are declared dead.

False negatives eliminated

  • Grouped User-agent lines in robots.txt (User-agent: GPTBot / User-agent: PerplexityBot / Disallow: /) now attribute the rules to every listed bot. Previously only the last agent in the group was detected, so AI-crawler blocks could go unreported.
  • The www/apex duplicate-content check now tests the real apex domain. For sites already on www., it previously probed www.www.example.com and silently verified nothing.
  • The generic image filename check now actually sees image files — they were never collected during the file walk, so the check passed unconditionally.

Honest results

  • Cross-page title and description uniqueness now report as skipped when only the homepage was fetched, instead of fabricating a pass.
  • Article, FAQPage, and BreadcrumbList schema checks no longer fail pages they never fetched — they report as skipped with an explanation until multi-page auditing lands.
  • Core Web Vitals from CrUX field data. LCP, CLS, INP, and TTFB now come from the real-user field data in the PageSpeed Insights response — the data Google actually ranks on — with lab data as fallback. INP was previously always unavailable because it read a lab audit that no longer exists.
  • New check: twitter-card-missing — flags pages without a twitter:card meta tag. Fix page.
  • PageSpeed opportunities surfaced. Lighthouse improvement opportunities (render-blocking resources, unused JavaScript, and so on) now appear as info-level findings.
  • New INFO section in terminal output — info-level suggestions were previously collected but never displayed.
  • Integration test suite — fixture-based tests (npm test) lock in the detection and false-positive fixes.
  • Version string is read from package.json once instead of being hardcoded in six places.
  • Unused dependencies removed (@babel/traverse, @babel/types); dead code removed (unreachable readline prompt, unused collected fields).
  • SvelteKit build output (.svelte-kit, build) and deploy artefacts (.vercel, .netlify) are excluded from the file walk.
  • Vue SFCs with both <script setup> and a plain <script> block are now fully scanned.
  • Docs and README now show the working install command (npx orino-cli audit).