Skip to content

Browser Support Test — C# source

Audit your real browser against 30 modern web capabilities - WebGPU, WASM, WebAuthn, Service Workers and more. Get a weighted readiness score, copy-paste detection snippets, and a shareable link.

This is the C# implementation — the same logic the interactive tool runs, in a shareable, citable form.

// browser-support-test — C# polyglot showcase port.
//
// Runtime capability probe, weighted score, and support tier.
//
// This is the C# sibling of src/tools/BrowserSupportTest.tsx (+ the
// browser-support/* modules) that powers the live tool.
//
// ILLUSTRATIVE PORT: the live tool detects *browser* features at runtime
// (navigator/window probes) — a browser-only concern that cannot run in a
// non-browser CLR process. This port shows the ANALOGOUS pattern for .NET:
// probes query the live runtime surface (RuntimeInformation,
// OperatingSystem, System.Runtime.Intrinsics, RuntimeFeature) — the
// mechanism .NET uses to gate platform features, and the direct equivalent
// of `'feature' in window`. The scoring algorithm and tier thresholds
// below are byte-for-byte the same as the TypeScript lib's; only the probe
// targets differ.
//
// Language: C# (12 / .NET 8, standard library only).
// Ported from src/tools/BrowserSupportTest.tsx (+ browser-support/* modules).
// Source: CosmoDev polyglot showcase port.
// License: display source — part of CosmoDev's polyglot tool pages.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace CosmoDev.Polyglot.BrowserSupport;

/// <summary>Runtime capability probe, weighted score, and support tier.</summary>
internal static class BrowserSupportTest
{
    private const string Supported = "supported";
    private const string Limited = "limited";
    private const string Unsupported = "unsupported";
    private const string Unknown = "unknown";

    /// <summary>One capability the audit can check. <paramref name="probe"/>
    /// returns true when the capability is present in THIS runtime.</summary>
    private readonly record struct Check(string Id, string Title, string Category, double Weight, Func<bool> Probe);

    /// <summary>Outcome of one probe.</summary>
    private readonly record struct FeatureResult(string Id, string Status);

    /// <summary>Contribution × weight. Same values as src/tools/browser-support/score.ts.</summary>
    private static double Contribution(string status) => status switch
    {
        "supported" => 1.0,
        "limited" => 0.5,
        "needs-https" => 0.3,
        _ => 0.0, // unsupported, unknown
    };

    /// <summary>Weighted readiness 0–100; matches computeScore() exactly.
    /// Results whose id isn't in the catalog are ignored.</summary>
    private static int ComputeScore(FeatureResult[] results, Check[] catalog)
    {
        double earned = 0.0;
        double possible = 0.0;
        foreach (var r in results)
        {
            foreach (var c in catalog)
            {
                if (c.Id != r.Id) continue;
                earned += Contribution(r.Status) * c.Weight;
                possible += c.Weight;
                break;
            }
        }
        if (possible == 0.0) return 0;
        return (int)Math.Round(earned / possible * 100); // banker's rounding, as in Python's round()
    }

    /// <summary>tier_for mirrors tierFor() in the island — same thresholds.</summary>
    private static (string Label, string Tone) TierFor(int score) => score switch
    {
        >= 90 => ("Fully modern", "text-success"),
        >= 75 => ("Very capable", "text-success"),
        >= 55 => ("Capable, minor gaps", "text-accent"),
        >= 35 => ("Showing its age", "text-fg-muted"),
        _ => ("Legacy browser", "text-danger"),
    };

    // Probes. RuntimeInformation / OperatingSystem / System.Runtime.Intrinsics
    // query the live CLR — .NET's equivalent of `'feature' in window`.

    /// <summary>Representative catalog of .NET runtime capability probes.</summary>
    private static Check[] Checks() =>
    [
        new("ptr-64", "64-bit process", "Platform", 1.0,
            () => Environment.Is64BitProcess),
        new("unix", "Unix platform", "Platform", 2.0,
            () => OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsFreeBSD()),
        new("arm64", "ARM64", "Cpu", 2.0,
            () => RuntimeInformation.ProcessArchitecture == Architecture.Arm64),
        new("sse2", "SSE2", "Cpu", 2.0,
            () => System.Runtime.Intrinsics.X86.Sse2.IsSupported),
        new("avx2", "AVX2", "Cpu", 2.0,
            () => System.Runtime.Intrinsics.X86.Avx2.IsSupported),
        new("aes-ni", "AES-NI", "Cpu", 2.0,
            () => System.Runtime.Intrinsics.X86.Aes.IsSupported),
        new("dynamic-code", "Dynamic code", "Runtime", 3.0,
            () => RuntimeFeature.IsDynamicCodeSupported),
    ];

    /// <summary>Run probes; a throw degrades to 'unknown' so one failure
    /// can't abort the audit.</summary>
    private static List<FeatureResult> RunChecks(IEnumerable<Check> catalog)
    {
        var results = new List<FeatureResult>();
        foreach (var c in catalog)
        {
            string status;
            try
            {
                status = c.Probe() ? Supported : Unsupported;
            }
            catch (Exception)
            {
                status = Unknown;
            }
            results.Add(new FeatureResult(c.Id, status));
        }
        return results;
    }

    public static void Main()
    {
        var catalog = Checks();
        var results = RunChecks(catalog);
        int score = ComputeScore(results.ToArray(), catalog);
        var (label, _) = TierFor(score);
        int supported = results.Count(r => r.Status == Supported);
        Console.WriteLine($"{RuntimeInformation.FrameworkDescription} · {RuntimeInformation.OSDescription}");
        Console.WriteLine($"{supported}/{results.Count} capabilities · readiness {score} · {label}");
        // Silence unused warnings when Limited is intentionally absent from probes.
        _ = Limited;
    }
}

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →