Седмицата (21–26 септември)

Post Syndicated from Надежда Радулова original https://www.toest.bg/sedmitsata-21-26-septemvri/

Седмицата (21–26 септември)

В края на миналото хилядолетие дядо ми на шега наричаше комшиите, насядали „на мохабет“ по пейките пред домовете си, „радио Фустанела“. С други думи, на тази жива „медия“ не можеше и не трябваше да се вярва, защото 90% от съдържанието ѝ беше изопачена информация, клюки, интриги и градски легенди. Но какво да се прави, по онова време интернетът все още беше оскъден, мобилните телефони не бяха по/в джоба на всеки, а и имаха копчета като на пишеща машина за сметка на голям екран.

Сега интернетът е в пъти повече от водата през лятото в някои райони на България. А според безплатния ми домашен ИИ българинът прекарва средно между 25 и 30 часа седмично онлайн, като около 17 от тях са посветени на социално „мрежуване“ (рядка дума, заловена за ушите от Павлина Върбанова). Ако дядо ми беше жив, щеше да се изуми какво завидно национално покритие е постигнала тази развъртяна новотехнологична „фустанела“.

Наскоро, скитайки се из Гърция, забелязах как интернетът там –  и по туристически места, и по не дотам… – хич го няма, а като го има, си казваш „по-добре да го нямаше“, защото непрекъснато прекъсва. И какво правят хората без интернет, ще попитате. Ами добре са, пият кафе и узо, говорят си, разлистват вестници, списания и книги на хартия. Като ги попиташ нещо, те гледат в очите, отговарят, без да бързат, палците им не потрепват невротично, нетърпеливи за следващия скрол. С всичко това ни най-малко не искам да омаловажа положителната роля на интернет. Но ако дозата прави отровата, то, струва ми се, отдавна сме предозирали. На всичкото отгоре ефектите от предозирането са видими на много нива:

1) Бързият и относително евтин интернет в България ни даде поне по една допълнителна квалификация. Всички вече сме половин доктори, една трета политолози, почти завършени криминални психолози и напълно завършени философи, педагози и историци, най-често без да сме образовани в нито една от гореизброените области.

2) При непрестанния приток на разнопосочна информация въпросът дали тя е проверена, или не, престава да има особено значение. Защото непроверената информация ни освобождава от необходимостта да поемаме отговорност за думите, които самите ние хвърляме в мрежата. Та нали всичко се превръща в стръв. И чудна работа – рибата кълве ли, кълве.

3) Парадоксално започнахме да вярваме на всякакви небивалици, но заедно с това да не вярваме на нищо, дори на собствените си очи. Така освен трайно недоспали постепенно се превръщаме в недоверчиви, недоволни, неразбрани, недооценени и като цяло неприятни хора. А в крайна сметка – и дълбоко неинформирани. Само че идват избори. И това да сме такива, в каквито се превърнахме – заспали лапнишарани, – върши чудесна работа на някои стари рибари, които са в час както с някогашното мрежуване, така и със сегашния нетуъркинг.

Пресен е примерът с изборите в Германия, където интернет платформи се превърнаха в трибуни на предизборните кампании, ускориха поляризацията, отнеха от силата на центъра и доведоха до ярко разделение на политическата карта – радикалнолеви в Берлин, крайнодесни в източните провинции. И ако „Алтернатива за Германия“ се окопа в TikTok, YouTube и X, левите заложиха на Instagram, Telegram и локални блогове. У нас като че ли липсва такава дигитална стратификация и както обикновено, газим в добре познатия ни повсеместен мишмаш. Но това, че ни е добре познат, не го прави по-малко опасен… Та затова в края на лятото стигам до следния извод: повече кафе, узо и разговори на живо, по-малко скрол. Повече четене на дълги текстове (над 8000 знака), по-малко скрол. Повече засаждане на растения (ей сега иде времето на лалетата и зюмбюлите), по-малко скрол. И без това влизаме в сезона на мъглите, нека поне разсеем мозъчните.

И да, ако четете „Тоест“, няма да сгрешите. „Тоест“ също е в интернет, но текстовете, които публикуваме, миришат на мастило, проверени са всякак и отвсякъде и плуват в свободни води, незасегнати от ловно-рибарския медийно-политически сезон. Подкрепете ни (вижте бутона най-долу), за да продължим да развиваме този малък резерват на разума, активното гражданство и добрия вкус.

В началото на лятото писах тук за боклука в курортните ни градове. Виждам, че това е и една от темите на Веселин Златков в неговите „6 раздувки за варненското лято 2026“.

6 раздувки за варненското лято 2026

Какъв беше туристическият сезон във Варна – няколко наблюдения от Веселин Златков. Зад обичайните сметки за брой туристи, приходи и (не)успешен сезон се вижда един град с по-дълбоки проблеми и с жители, които успяват да са недоволни от почти всичко. Което, ще се съгласите, е забележителен талант.

Боклук, затруднен достъп до града, високи цени, отблъскваща миризма и лоша храна. Какво повече му трябва на човек за един гарантиран летен кошмар? А, да, хейт, злоба, агресия… И това го имаме в изобилие. Остава ни със стаен ужас да очакваме какво ще ни донесе лятото на 2027-ма – на нас и на клетите туристи, които ще се изсипят покрай „Евровизия“.

„Красота и катастрофа“ – така би могъл да се казва текст за днешна Варна (а и за други български градове), но всъщност става дума за един фикционален Париж от може би най-награждаваната видеоигра за всички времена –„Светлосянка: Експедиция 33“. В този брой Миглена Николчина и Северина Станкева продължават разговора си за нея и ни обнадеждават, че останалото в миналото велико изкуство

може да бъде преродено в различни форми, включително във виртуалния свят на игрите, където да продължи съществуването си в тази нова естетическа вселена.

Красота и катастрофа в „Светлосянка: Експедиция 33“ (втора част)

След лятната ваканция Миглена Николчина и Северина Станкева продължават разговора си за навярно най-награждаваната игра на всички времена. А във времена на катастрофични прогнози явно е дошло времето да поиграем на катастрофа. Но и да се върнем в голямото изкуство, макар и вървейки през руини.

Нашата стара вселена обаче продължава да крие големи тайни, една от които е възможността за съществуване на извънземен разум. Убедена съм, че със или без интернет, всеки би могъл да пусне пет стотинки по тази тема: едно ще кажат учените, друго – ясновидците, трето и четвърто – религиозните авторитети. В нашия случай нещото го казва Атанас Шиников в продължението на текста си „Господът на световете“. Извънземни и ислям“. На мен лично ми хареса връзката между извънземни и джинове. Възнамерявам да си я запазя за частни творчески проекти.

„Господът на световете“. Извънземни и ислям (продължение)

Ако в първата част на статията си Атанас Шиников отнася извънземния си въпрос към Корана и традиционните ислямски авторитети, в продължението изследва порталите за фетви, за да научи кой е джин, кой – човешки син и дали те (космическите същества) са „някъде там“ или по-скоро някъде тук.

За разлика от сложно доказуемата връзка между извънземни и ислям, връзката между съвременните демокрации и избирателните системи е видима с просто око. През ноември са междинните избори в САЩ и Йоанна Елми посвещава на тях брой 18 от бюлетина „Гласовете на Америка“. Доверието в Тръмп изглежда поразклатено, макар и не сринато, но заедно с това се наблюдава отлив на подкрепата и за двете партии по отношение на определени болни теми, например развитието на изкуствения интелект. И изобщо, ставаме свидетели на интересна тенденция:

реалното усещане за реалните проблеми и реалните последствия като обединяващо избиратели от двата края на политическия спектър. 

Гласовете на Америка. Междинните избори – брой 18

Междинните избори наближават, а американците са все по-недоволни от икономиката, изкуствения интелект, естествения интелект (на политиците) и въобще… Какво може да размести силите през ноември и къде партийните разделения отстъпват пред общите проблеми – в месечния бюлетин за САЩ на Йоанна Елми.

Дали подобна тенденция ще моделира изхода от предстоящите президентски избори у нас, предстои да видим. На първо четене свиващата се като неправилно изпран вълнен пуловер партия ГЕРБ се цепи по оста Йотова–Гюров, която пък в голяма степен се припокрива с оста проруска–проевропейска ориентация. Доколко ГЕРБ все още е лидерска формация или вече е подвластна на центробежни сили, ще се разбере вероятно едва на балотажа. Повече за тези процеси четете в седмичния анализ на Емилия Милчева „Анатомия на едно разпадане“.

Анатомия на едно разпадане

Когато властта вече я няма, какво остава от партия, чиято най-силна идеология е била властта? Президентските избори могат да покажат от какво всъщност е съставен електоратът на ГЕРБ и докъде стига лоялността му към Бойко Борисов. От Емилия Милчева.

Но до изборите има още няколко седмици, в които да помислим – с главите си, а не с колективния интернет разум – кой от кандидатите какво ни казва и защо. А междувременно, докато вадим есенните шлифери и усещаме с кожата си липсата на

пастьозното зелено на смокините
и матовото синьо на небето,

може да прочетем стихотворението на месеца. Казва се „Полуостров“, а авторката е Боряна Кацарска. С него ви напомняме, че с добрата литература никога не сме самотни острови, а най-малкото ставаме част от архипелази, което пак си е нещо, особено в сезона на нахлупените ушанки и замръзналите носове.

Полуостров

аз няма никога да мог’ да се измъкна Той няма никога да мож’ да се изплъзне
от жилавата пъпна връв със сушата
и в осоления и гладък въздух
остава му да гледа и да слуша
огънатата ивица на плажа
полепналите по скалите къщи
едва заобления хоризонт
завръщането
на едно и

От дума на дума стигнахме и до бутона, за който ви споменах по-горе (не е като да не сте били предупредени). Сега вие сте на ход.

Благодарим ви!

Friday Squid Blogging: Participatory Squid Dissection in October in Tennessee

Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2026/09/friday-squid-blogging-participatory-squid-dissection-in-october-in-tennessee.html

I feel like someone who reads this blog will want to go to this:

Families are invited to dive into the fascinating world of marine biology during an exciting, hands-on Family Squid Dissection at the Hands-On Science Center. Designed for curious learners of all ages, this unique experience combines an interactive lesson with the opportunity to explore the anatomy and adaptations of real ocean life.

[…]

During the guided squid dissection, each family will work together to examine a squid up close, exploring its organs, structures, and specialized features. The experience provides a memorable opportunity for children and adults to see firsthand how the anatomy of a squid helps it survive in its underwater environment.

If you go, take pictures.

As usual, you can also use this squid post to talk about the security stories in the news that I haven’t covered.

Blog moderation policy.

AMD Takes the Lid off of Next-Gen EPYC 9006 Venice As Zen 6 Comes to Servers

Post Syndicated from Ryan Smith original https://www.servethehome.com/amd-takes-the-lid-off-of-next-gen-epyc-9006-venice-as-zen-6-comes-to-servers/

The launch of AMD’s next-gen EPYC 9006 processors is quickly approaching. Today we are looking at AMD’s complete 6th gen EPYC lineup, and what to expect from the company between now and late 2027

The post AMD Takes the Lid off of Next-Gen EPYC 9006 Venice As Zen 6 Comes to Servers appeared first on ServeTheHome.

Trading a Cloud Identity for Your Own: Workload Attestation on Managed Compute

Post Syndicated from Netflix Technology Blog original https://netflixtechblog.com/trading-a-cloud-identity-for-your-own-workload-attestation-on-managed-compute-516d5a29b252

By Dhruv Pratap

Introduction

Organizations that have been around for a while usually run two identity systems side by side. One belongs to the cloud provider: IAM roles, instance profiles, execution roles. The other is your own, and it is the one your internal services actually check when they decide whether to answer a request.

On infrastructure you build yourself, you can bootstrap your own identity however you like. On managed compute you cannot. The provider hands your process a cloud identity and nothing else.

This post describes how we close that gap for Apache Spark workloads running on Amazon EMR. A workload that starts with only an AWS identity has to end up holding a first-class internal identity. Doing the exchange is straightforward. Making it trustworthy is the part that took the design work. Very little of what follows is specific to Spark or to EMR.

Two identity systems

Internal service-to-service authentication at Netflix runs on a private PKI called Metatron. Every workload gets a short-lived X.509 certificate, and services authenticate each other with mutual TLS. A workload cannot simply ask for a certificate. It is issued only after the identity service has satisfied itself that the requester really is the workload it claims to be. That verification step is called attestation. In each environment we support (VMs, containers, functions) attestation rests on some environment-specific proof that the platform can check on its own.

The second concept is the Data Project, which is our unit of ownership for data. A Data Project owns tables, has a set of authorized users, and has an identity of its own. Jobs run as the Data Project rather than as the person who launched them. That is what keeps table-level access control and audit consistent across scheduled and interactive use.

So the problem is this. A Spark job on managed compute starts with an AWS execution role and no internal identity. Everything it needs from inside the company (reading an encrypted column, evaluating table ACLs, holding an interactive session open longer than a short-lived token lasts) requires the internal one.

One identity, one role

The design rests on a decision made outside the Spark stack entirely. Each Data Project identity maps 1:1 to a dedicated IAM role, and the service that owns Data Project metadata records that mapping.

The mapping is what makes translation possible. It lets a statement in the provider’s vocabulary (“this process is running as role R”) become a statement in ours (“this process is workload W”). Without it there is nothing to translate into, and no amount of cryptography helps. The hard part of bridging two identity systems is rarely the protocol. It is committing to a mapping and then keeping it authoritative.

One practical objection arrives immediately. A single AWS account cannot hold tens of thousands of IAM roles, and we expect data projects in the order of ten thousands. We handled this by sharding data project roles deterministically across a small pool of dedicated accounts, which scales well past the projected number of projects and has the useful side effect of keeping workload roles on the far side of an account boundary from the control planes that launch them.

Components

Five components take part.

The control plane is the only service allowed to launch Spark jobs. It resolves the Data Project’s IAM role, builds and signs a workload metadata payload, and submits the job with that role as the execution role. It holds a signing key issued to it for this purpose alone.

The Data Project service is the authority for the identity-to-role mapping.

The Identity service receives attestation requests, verifies them, and issues certificates.

A Spark plugin provides the hook. Spark 3.0+ added a plugin interface with driver-side and executor-side components that are initialized while those processes are bootstrapping.

AWS STS acts as a notary, which is not its usual job.

Step one: the control plane makes a signed claim

When a job is submitted, the control plane validates the caller, looks up the Data Project’s IAM role, and builds a small payload describing the workload it is about to launch. The payload names the application identity, the mapped role, and the environment, stack and detail that the resulting credentials should be scoped to. The control plane signs the payload and passes it and the signature through as ordinary job configuration.

Two properties of this step matter. First, only one service can produce a valid signature, so the set of things that can assert “this workload is legitimate” is small and auditable. Second, the payload is a claim rather than an authority. On its own it proves nothing, because job configuration travels through infrastructure we do not fully control and anything that can read it can replay it.

Step two: the workload proves it holds the cloud identity

When the managed service launches the driver process, it does so under an OS user that has the execution role’s credentials available. The driver-side plugin initializes and uses those credentials to sign, but not send, a request to the provider’s identity endpoint (sts:GetCallerIdentity). The result is a short-lived pre-signed URL.

That URL is a transferable proof of possession. Anyone can fetch it. Only the holder of the role’s credentials could have produced it. And the response comes from AWS rather than from the workload, stating which role signed the request. The workload cannot lie about the answer because the workload does not supply the answer.

The pattern is not new. It is the same idea behind AWS IAM authentication in HashiCorp Vault and in AWS’s own function attestation flows. It generalizes well: any environment that gives a process cloud credentials and nothing else can still produce a verifiable statement about its own identity.

The plugin sends one attestation request carrying both artifacts, the pre-signed URL and the signed metadata.

Step three: corroboration

The identity service does four things.

  1. It fetches the pre-signed URL against AWS STS and reads back the role that signed it. This is the provider’s statement.
  2. It verifies the metadata signature against the key issued to the control plane. This is the platform’s statement.
  3. It corroborates the two. The role AWS reports must be the role the control plane said it dispatched, for the identity the metadata names.
  4. It issues certificates for that identity, scoped to the environment, stack and detail from the signed metadata.

Step 3 is the point of the whole design. Neither statement is sufficient by itself, and they fail in complementary ways. The provider’s statement is unforgeable but under-specified: it gives you a role, and a role is not a workload. It says nothing about why this process exists or what it should be allowed to be. The platform’s statement is well-specified but unverifiable on its own, for the reasons above. Put together, the signature says the workload was legitimately dispatched and the pre-signed URL says this really is it. Neither party has to trust the workload’s own account of itself.

There is a tension here that we settled deliberately, and other teams should expect to meet it. The provider’s answer identifies a role, not an application. Deriving an application name from a role name is fragile string matching, and the session identifiers the platform assigns are not under our control. We chose to take the application identity from the signed metadata and use the provider’s answer only for corroboration. That costs a network round trip and a stricter signing requirement, and it buys a much clearer trust story.

The fan-out problem

A Spark application is one driver and up to thousands of executors, created and destroyed throughout the life of a job. Attestation designed around one process per host does not survive that.

There are two defensible answers.

In the first, each executor attests independently. This is uniform, adds no new trust boundary, and grounds every process’s identity in the same provider-verified proof. The cost is amplification. One large job can produce thousands of STS calls and thousands of attestation requests in a burst, which looks a lot like an attack and creates a hard dependency on provider-side rate limits.

In the second, executors inherit credentials from the driver. The driver attests once and distributes credentials to executors over Spark’s internal RPC, which we configure with authentication and AES-GCM encryption so that only processes in the same application can take part. Load on the identity service stays constant. The cost is a second trust boundary and a driver that is now a credential distribution point.

Considering our scale at Netflix here we went with the second approach. The general lesson is that identity amplification is a capacity question, and it is better to answer it on purpose than to have it answered for you during an incident.

Lifecycle

Certificates are short-lived by design, so bootstrapping is only half the work. On self-managed hosts a system service handles renewal. Inside managed compute there is no equivalent hook, so the driver JVM runs a timer that re-attests on a fixed interval, well ahead of expiry. Credential material is written to a temporary directory readable only by the process owner and removed when the process exits.

Executors do not refresh. They are usually short-lived, and an executor that somehow outlives its credentials can exit and be replaced, which is cheaper than making every executor a renewal client.

The rule worth carrying into any similar system is that attestation has to be a repeatable operation rather than a bootstrap step. Anything that can only happen once at process start will eventually be the reason a long-running job dies nine hours in.

Why this generalizes

If you run your own identity system and are moving workloads onto managed compute, the specific services here matter less than the shape of the solution.

  1. Anchor on one exchangeable primitive. A single authoritative 1:1 mapping between your identity and a provider identity is what makes translation possible. The rest is plumbing.
  2. Require two independent claims and corroborate them. One from the provider, unforgeable and under-specified. One from your control plane, well-specified and replayable. Trust the intersection and never either alone.
  3. Keep the signer scarce. If exactly one service can make the platform’s claim, your trust story fits in a sentence.
  4. Hook the layer you still own. On managed compute you rarely control the host or its init system, but you almost always control the runtime: a plugin, an agent, an entrypoint. Attestation belongs there.
  5. Decide the amplification policy on purpose. Distributed engines multiply every per-process operation by their parallelism.
  6. Make attestation repeatable and credentials short-lived. Renewal is a requirement, not a follow-up.

What makes the result trustworthy is that no single participant issues an identity by itself. Not the workload, not the control plane, not the provider. And the workload, which is the party in the weakest position to be trusted, is never asked to vouch for itself.

Acknowledgements

Thanks to Amer Hesson for the Data Project abstraction, Nick Siow for the Data Project IAM role sharding, and Doug Clark for Metatron attestation.


Trading a Cloud Identity for Your Own: Workload Attestation on Managed Compute was originally published in Netflix TechBlog on Medium, where people are continuing the conversation by highlighting and responding to this story.

[$] How KDE got funding to add enterprise features

Post Syndicated from jzb original https://lwn.net/Articles/1096245/

The Sovereign Tech Agency (STA) is
investing nearly €1.3 million
in KDE through 2027. At Akademy 2026
in Graz, Austria, Nate Graham and Kevin Ottens, two of the contributors who
helped bring in the investment, explained how the funding was secured, provided
tips on how projects should approach organizations like STA, and talked about
how that money will be improving KDE for everyone. In addition to keeping the
community informed about the work, the pair hoped to pass on what they have learned
to encourage others to help raise funds for development as well.

Improving site performance by shipping more CSS

Post Syndicated from Josh Black original https://github.blog/engineering/architecture-optimization/improving-site-performance-by-shipping-more-css/


The Primer Design System powers many of the experiences you see on GitHub today. From buttons to banners to breadcrumbs, these foundational components are required to be accessible, flexible, and performant across a wide variety of scenarios.

Back in 2023, the number of components on certain pages began to explode. This led to several performance-related challenges with our existing CSS-in-JS solution:

  • Initial page loads took longer due to styles being initialized on the client
  • Server-side rendering performance declined as style collection shifted from the client
  • Updates to styles grew out of control as component count grew on a page

It became clear that the Primer team needed to address the issue at the source. We needed to find an alternative that would completely avoid the client and server costs that we were seeing with our current solution. Most importantly, any alternative we pick would need to work in a way that would avoid any breakage to GitHub during the migration.

Introducing CSS (Modules)

The Primer team found a solution that met all of our criteria: CSS Modules. This format would allow us to do one of our favorite things: write and use native CSS features, while still allowing some amount of the colocation and encapsulation that we had come to expect from CSS-in-JS.

With CSS Modules, styles would be authored in a CSS file alongside the JavaScript source for the component. It would also allow us to treat all class names as local by default, preventing some of the collisions and challenges that can come from global selectors. This format also removes the need for any client or server runtime behavior. Instead, styles would roll up into CSS stylesheets that were sent as part of the HTML for a page.

However, this solution was radically different from the CSS-in-JS solution we had at the time. This change would require an update to every Primer component and every component at GitHub authored using this technique. Thankfully, design systems are a perfect vehicle to deliver this kind of change at scale.

A gradual march towards CSS Modules

The situation for moving towards CSS Modules was clear. The Primer team would need to deliver updates to each of its components, moving them from CSS-in-JS to CSS Modules. At the same time, updates we made to these components could not break any usage in GitHub. Finally, the underlying technique we used for CSS-in-JS also had to continue working for any components in GitHub that were currently using it.

With all these constraints in place, we decided on an incremental migration strategy that would allow us to safely ship component updates without breaking the world. For each component, our plan was to:

  • Add a new file that translated existing styles to CSS Modules
  • Add the component to a feature flag that would toggle between the new and old styles
  • Use existing visual regression tests to verify snapshots were identical between our CSS-in-JS solution and CSS Modules
  • Gradually roll out the feature flag to our team, then to GitHub staff, and finally to all GitHub users to catch any issues along the way

This process created a strong feedback loop where issues were flagged early in the process as Primer continuously delivered these changes to GitHub. The use of feature flags allowed us to do this migration safely while giving us clear signals on the performance benefits of CSS Modules.

By December 2024, all components in Primer were migrated over to CSS Modules using this process. We saw performance wins across the board, in particular:

  • 55% less time to server-side render a page
  • 25% less time for components on a page to initialize

With clear performance wins from doing this work in Primer, we began to wonder if we could see similar performance wins by doing these conversions in other parts of GitHub. Similarly, how long until we could ultimately drop support for CSS-in-JS across the company?

Moving away from CSS-in-JS at GitHub

One of the trickiest parts about removing our CSS-in-JS solution from Primer was due to the usage of the sx prop. This prop was the way to style and customize components from Primer. Teams could provide an inline object to customize everything about the component. It represented the best and worst parts of CSS-in-JS:

  • Excellent TypeScript support with integration with our Design Tokens
  • Co-located with the component so that everything was in one place
  • High runtime cost due to the dynamic nature of inline objects used for sx
  • Difficulties scaling as the number of components using sx on a page grew

As a result, the first part of our journey to move away from CSS-in-JS was to reduce sx usage across GitHub. This would allow us to immediately improve performance similar to the wins we saw when migrating Primer components. It also set us up perfectly for removing CSS-in-JS entirely from the product.

The Duality of Primer

It’s important to note that, while the design system itself was officially off styled-components, a large part of the GitHub codebase itself wasn’t. With sx props having been the de facto styling standard at GitHub for years, we were looking at thousands of sx props that needed migration before we could even think of getting GitHub onto the sleek new @primer/react version which didn’t rely on styled-components.

So… how did we do this immense amount of work while increasing confidence and reducing risk? The answer: not all at once.

The original CSS migration was a little bit more nuanced than we led on: in addition to migrating the components to CSS modules, feature flagging to test in production and slowly rolling them out, we also created “wrapper” components in a transitive library we called @primer/styled-react. The whole purpose of this package was to allow sx usage into the newly migrated components. This way, the instances of the GitHub UI codebase that were using this prop could continue to consume them by importing the same component through @primer/styled-react, while we realized the performance gains of importing straight from @primer/react for the cases that didn’t.

Styled Box Zero

The next phase of the migration process was as follows:

  • On a package-by-package basis:
    • Translate all sxusage into equivalent CSS modules files. This included cross referencing (See migrating to CSS variables)
    • Replace @primer/styled-react imports with @primer/react imports
    • Test in pre-production
    • Deploy

Curiously enough, while we were getting ready to undertake this massive effort, styled-components maintenance mode was announced, offering further confirmation that we were taking steps in the right direction.

The work kicked off April 2025 with a peak of ~7,760 sxprops to be migrated; we wouldn’t see it realized until May 2026. Initially, one of our great in-house developers, Ian Sanders, created a VS Code plugin that would assist with per-prop migration. A similar codemod was developed internally and utilized to migrate entire files in the GitHub codebase. The work, while requiring a bit of manual oversight and careful validation, was mostly automated. A rotation of 8 engineers migrated 6,419 props over the course of 6 months, observing Server-Side Rendering time performance gains ranging from 1% up to 22% in some pages.

Table titled “Server Side Rendering” with a search field and columns for CATALOG_SERVICE, CONTROLLER, and IMPROVEMENT. It lists GitHub services and controllers with improvement percentages ranging from 3.05% to 21.97%, including a highest value of 21.97% for github/code_view / commit.

In a different side of GitHub, Copilot’s capabilities were increasing exponentially. AI was getting smarter, more capable; we released Copilot coding agent and Copilot code review while this work was still underway.

By the time we picked this work back up, now April of 2026, the panorama was different; we were able to get down from 895 to 0 sxprops in the span of three weeks with a team of two engineers, relentless determination, and a whole lot of Copilot coding agents.

Area chart titled “Total SX props” showing values declining from about 7,300 in May to near zero by June–July of the following year, with several short-lived spikes. Two highlighted points are labeled 6.87k around August and 5.37k around October.

Battle of the themes

It was a big day: we had finally completed the sx migrations that were standing between us and full styled-components removal, years in the making… we can finally clean up these dependencies and move on to different, more exciting work, right? Wrong!

GitHub supports seven different themes, all of which offer a high contrast mode variation. All of it enabled through, you guessed it, styled-components. Before we can even think of removing these dependencies, we need to decouple our theming.

Now, this isn’t as huge a deal as it sounds. Our theming variables have always been defined in CSS through our @primer/css package, and we already planned forward for non-styled Theming when we migrated @primer/react in late 2025. It’s the JavaScript usage and utilities that are enabled by styled-components that we needed to remove. Once again, we got to work.

You know the drill by now: perform the migrations, roll it out slowly, feature flag everything. Two months and a few hiccups along the way later, we were all-systems go for dependency removal; we even feature flagged that. Better safe than sorry.

All’s well that ends well

GitHub has been running on 100% CSS modules as of June 2026. The safeguards we put in place enabled us to roll out significant architectural changes safely, stress test in production, catch errors, pivot and repair efficiently, ultimately allowing us to succeed in our goals and realize great performance gains along the way.

What looked at first like a CSS migration turned out to be a gradual re-platforming of how GitHub styles, themes, and ships UI at scale. By the end, we had not only removed sx, styled-components, and styled-system from dotcom, but completed it without breaking GitHub along the way. Enhancing the performance, user experience and delight of our products continues to be top of mind for all of us here at GitHub.

The post Improving site performance by shipping more CSS appeared first on The GitHub Blog.

The collective thoughts of the interwebz