Navigate the contribution process for major open-source design systems — from finding good first issues to getting complex component PRs merged with the MUI, Radix UI, and shadcn/ui maintainers.
Navigate the contribution process for major open-source design systems — from finding good first issues to getting complex component PRs merged with the MUI, Radix UI, and shadcn/ui maintainers.
Each design system has distinct contribution entry points. MUI (most established): look for issues labeled good first issue and help wanted on GitHub; documentation improvements and bug reproductions are the lowest-friction entry points. MUI requires a Contributor License Agreement signature and a very detailed PR description. Radix UI: look for status: needs-implementation issues where the API is already designed but implementation is pending — these are ideal because the design decisions are made, you execute. The Radix team values accessibility precision above all else. shadcn/ui: a re-distribution of Radix components with specific Tailwind styling; contributions are often new component additions that must follow the shadcn registry format. The contribution bar is lower than MUI but requires complete TypeScript types, Tailwind variants, and a Storybook story.
Start with documentation before code: fixing a misleading example in docs, adding a common usage pattern, or improving an error message. This builds relationship with maintainers before a complex code PR.
Open-source design system PRs face higher scrutiny than internal PRs — tens of thousands of developers depend on them. MUI's quality checklist for a new component:
1## MUI Component Checklist
2
3### Code Quality
4- [ ] TypeScript strict with all prop types documented via JSDoc
5- [ ] Test coverage: unit tests (80%+), visual regression screenshots
6- [ ] StrictMode compatible (no double-effect side effects)
7- [ ] SSR/hydration compatible (no server/client mismatch)
8- [ ] No peer dependency changes without discussion in an issue first
9
10### API Design
11- [ ] Props follow MUI naming conventions (sx, slotProps, slots)
12- [ ] Composition via slots (not render props)
13- [ ] Polymorphic 'component' prop for element type override
14- [ ] API RFC discussed in a GitHub issue before PR is opened
15
16### Accessibility
17- [ ] axe-core: zero violations
18- [ ] Keyboard navigation: all interactions documented and tested
19- [ ] Screen reader tested (NVDA + Chrome, VoiceOver + Safari)
20- [ ] ARIA attributes: verified against ARIA Authoring Practices Guide
21
22### Documentation
23- [ ] Complete API documentation with all prop descriptions
24- [ ] Usage examples for all major use cases
25- [ ] Accessibility section explaining keyboard/screen reader behavior
26- [ ] Migration guide if this replaces an existing patternDo not open a code PR for a new component without a prior issue where the need and API are discussed. Maintainers close unannounced new component PRs regardless of quality.
A PR that gets merged in a major design system has three characteristics: it solves a clearly defined, confirmed-needed problem (from a tracking issue); it passes all automated checks with zero new warnings; and it anticipates maintainer concerns before they are raised.
For a bug fix contribution to Radix UI Select (keyboard navigation regression in iOS Safari):
1// Example: Radix UI contribution structure
2// 1. Reproduction case in the existing test file
3describe('Select keyboard navigation', () => {
4 it('closes on Escape in iOS Safari (regression test)', async () => {
5 // ...test implementation
6 });
7});
8
9// 2. Fix with inline comment explaining WHY (not just what)
10// In packages/react/src/select/Select.tsx:
11// iOS Safari dispatches keydown events with keyCode instead of key
12// for certain keyboard shortcuts when a virtual keyboard is shown.
13// Reference: https://bugs.webkit.org/show_bug.cgi?id=206865
14const normalizedKey = event.key ?? String.fromCharCode(event.keyCode);
15
16// 3. PR description:
17// Bug: Closes #1234
18// Root cause: WebKit bug 206865 — iOS Safari uses keyCode for escape
19// Fix: Normalize key detection to handle both key and keyCode
20// Tests: Added regression test for iOS Safari keyboard behavior
21// No API changes. No new dependencies. SSR-safe.Maintainer feedback in high-quality projects can be extensive and occasionally blunt. Respond professionally and treat every comment as a learning opportunity:
Common feedback patterns and responses:
Response time matters: respond within 48 hours of maintainer feedback. PRs that go quiet for 2+ weeks after feedback get closed. If you need more time, comment 'Still working on this — I'll have an update by [date].'
Every contribution to a major open-source design system teaches transferable lessons for internal systems. Document what you learned:
From MUI contribution: The slots + slotProps API pattern enables consumers to pass props to internal elements without exposing them all at the top level. This pattern works better than complex prop APIs for highly customizable components. Apply it to your internal Dialog's overlay, header, and content sections.
From Radix UI contribution: Headless components with no default styling are significantly more adoptable than styled ones. Consider publishing an unstyled variant of your most-adopted components for teams that want full styling control.
From shadcn/ui contribution: The registry distribution model (consumers copy component code rather than installing a package) removes upgrade friction entirely. Consider whether a 'copy-this-template' pattern works for your organization's most-customized components.
Process lesson: The 'issue before PR' requirement in all major projects is not bureaucracy — it prevents wasted effort on implementations that conflict with the maintainer's roadmap. Adopt this for Tier 3 contributions in your internal system.
Find one open issue labeled 'good first issue' in MUI, Radix UI, or shadcn/ui. Study 3 recently merged PRs in that repository to understand the expected quality and style. Start with a documentation improvement rather than code.
Your progress is saved in this browser, on this device only.