Key takeaways
- Relative repository paths keep documentation and its assets versioned together.
- Issue-upload URLs are convenient but less obvious to audit and migrate.
- External URLs reduce repository size but introduce another availability and privacy dependency.
README images can live in the repository, use a GitHub attachment URL, reference public storage, or use HTML for limited layout control. The best option depends on ownership, versioning, portability, and update frequency.
What matters most
- HTML image markup can set dimensions, though GitHub sanitizes unsupported elements and attributes.
- Generated status badges are useful when their service and fallback behavior are understood.
Choose an image location based on ownership and lifetime
A README image is a documentation dependency. Before choosing a URL, decide who owns the file, whether it must change with the code, how long it should remain available, and where the README will be rendered. A versioned architecture diagram has different requirements from a temporary pull request screenshot or a badge generated from live project data.
For example, keep installation screenshots beside the README when each release documents a different interface. A community logo shared across many repositories may belong in centrally managed public storage instead. Avoid choosing a location solely because it is convenient during editing. Moving images later can break old tags, package pages, forks, and links to historical documentation.
Repository file
Best for assets that should be reviewed, versioned, and released with the documentation.
GitHub attachment
Convenient for discussions and occasional README media, but its ownership and migration path are less visible than a tracked file.
External URL
Useful for centrally maintained or frequently changing assets, with an added availability, privacy, and access-control dependency.
Generated image
Appropriate for nonessential status information when readers can still understand the project if the generator is unavailable.
Keep release-specific media in the repository
For a tracked asset, place the file in a predictable directory such as docs/images/ and reference it with Markdown like . Relative paths make the README and image move together across branches and forks. Resolve the path from the Markdown file's location, not from the repository root, because a README inside a subdirectory has a different base path.
Treat path spelling as code. Case differences may work on one developer's filesystem but fail elsewhere. Renaming a directory, squashing an image, or deleting an apparently unused file can also break older documents. Review image changes with the text that depends on them, and use descriptive filenames rather than opaque names copied from a screenshot utility.
Pin documentation images to a stable revision when the page describes a released interface or behavior. A branch-relative path is convenient while editing, but the same README can show different artwork after the branch changes. Release notes, security advisories, and versioned setup instructions benefit from immutable references because readers can then see the image that belonged to that exact version rather than the newest replacement.
Relative path
Usually the most maintainable reference for an image committed alongside the README.
Default-branch URL
Always follows that branch, which is useful for current documentation but can make old references display newer artwork.
Commit-pinned URL
Provides an immutable view for releases or audits, but requires deliberate updates when the image changes.
Treat attachments and remote images as external dependencies
Dragging an image into a GitHub editor can produce a hosted attachment URL. That is fast and avoids adding binary data to the repository, but the resulting asset is not represented by a normal file in Git history. Record why the URL exists, keep the original somewhere controlled, and verify that repository transfers or documentation migrations will not leave the team without a manageable source.
A remote URL can reduce repository size and let one asset update across multiple documents. It can also fail because of an expired signed URL, changed access policy, deleted object, DNS problem, or hotlink restriction. Use an HTTPS location intended for durable public access, confirm that redistribution is permitted, and avoid embedding private endpoints. A request to an external image host may disclose reader network or browser information, so privacy-sensitive projects should minimize unnecessary third-party resources.
Use Markdown for meaning and HTML only for needed layout control
Standard Markdown is the portable default: . It expresses the image's purpose and works across more repository browsers, package registries, documentation generators, and local preview tools. Keep optional hover titles secondary because keyboard and touch users may never receive them, and because a title does not replace alternative text or a visible explanation.
An HTML img element can set dimensions when a screenshot otherwise dominates the page. GitHub sanitizes unsupported HTML, attributes, and styles, so elaborate positioning may disappear or behave differently from a local preview. Prefer a simple element with src, alt, width, and height. Base64 data URLs make Markdown large, difficult to review, and poorly portable; they also prevent normal file caching and should not be the routine answer to asset management.
Prepare images for the size at which people read them
Do not commit a full-resolution desktop capture when the README displays it in a narrow content column. Resize close to the useful reading width, while retaining enough pixel density for sharp text on high-density screens. Compression should remove waste without turning interface labels into artifacts. Compare the optimized result at its rendered size rather than judging only the file-size number.
Choose the format from the content. JPEG suits photographic images that do not need transparency. PNG remains useful for crisp interface captures, limited-color diagrams, and transparency, although it can become large. WebP can work for mixed imagery when every intended renderer is tested. SVG is effective for diagrams and logos created as vectors, but only trusted SVG should be published. Keep an editable source for diagrams even when the README uses an exported raster version.
Crop first
Remove browser chrome, empty margins, and unrelated application areas before resizing.
Preserve legibility
Check small labels, terminal text, and thin diagram lines at the final display width.
Remove sensitive metadata
Inspect filenames, embedded metadata, visible account details, access tokens, and notifications before committing.
Control repository growth
Replacing a large binary does not remove its earlier versions from Git history, so optimize before the first commit.
Write alternative text for the image's role
Alternative text should convey what a reader needs from the image in this context. For a successful test screenshot, describe the relevant success state rather than listing every visible control. For a diagram, summarize the relationship it illustrates and explain complex details in nearby prose. Do not repeat a caption word for word or use a filename such as screen-final-2.png as the description.
A linked image needs text that communicates the link's destination or action, not merely its appearance. Decorative separators and repeated brand marks should have empty alternative text when the renderer permits it, while status badges should receive concise labels such as Build: passing. Essential commands, configuration, or error messages must also appear as selectable text because images cannot provide a reliable copy, search, translation, or zoom experience.
Make artwork survive themes and missing resources
Transparent logos and diagrams often assume a white canvas. On a dark theme, black strokes can disappear; on a light theme, white labels can vanish. Test both themes and add an intentional background or border when one asset can serve both. If the renderer supports theme-specific picture sources, keep the light and dark versions semantically equivalent and give the overall image one useful alternative description.
Design the surrounding paragraph so the README remains understandable while an image is loading or unavailable. Never put the only installation step, security warning, or compatibility requirement inside a screenshot. Avoid meaning conveyed only by color, and check diagrams at increased zoom. These practices support accessibility while also making documentation more resilient in text-only tools, cached package pages, and restricted networks.
Use badges as summaries, not as the source of truth
A badge is a remotely generated image that summarizes changing data such as a build result, package version, or coverage state. Its accuracy depends on the upstream service, query parameters, branch selection, authentication, caching, and refresh behavior. Link the badge to a page where readers can inspect the underlying result, and label it so the meaning is clear without decoding color.
Keep the badge row selective. A long sequence of service calls slows rendering, creates visual noise, and increases the number of parties contacted when someone opens the README. Never use a badge as the only notice of a security issue or supported version. If a provider fails, the project description and normal contributor workflow should still make sense.
Review images as part of documentation testing
Preview the README in GitHub's renderer after committing to a branch. Open every image, verify relative paths from the actual README location, switch color themes, and inspect narrow and zoomed layouts. When the README is published to a package registry or documentation site, test that surface too because relative URL rules and supported HTML can differ.
Add lightweight operational checks for important assets. A link checker can detect missing remote images, while repository review can catch oversized binaries and untracked source files. Revisit screenshots when the interface changes, and remove obsolete assets only after searching all branches of maintained documentation. The goal is not merely a rendered image today, but an understandable document throughout the project's supported lifetime.
Rendering
Verify the repository page, forks, release tags, package mirrors, and any generated documentation that consumes the README.
Accessibility
Review alternative text, text contrast, theme behavior, zoom, and whether essential information is available outside images.
Performance
Check encoded dimensions, transfer size, badge count, and whether multiple full-resolution screenshots are necessary.
Governance
Confirm ownership, license, editable source, update responsibility, and a migration plan for externally hosted assets.
Technical details worth knowing
- Relative image URLs are resolved differently on a repository page, package registry, copied Markdown file, and external documentation renderer, so portability should be tested.
- Alternative text should communicate the image’s purpose without repeating the nearby caption; decorative badges can use concise labels instead of verbose filenames.
- Badges are remotely generated images whose availability, caching, privacy, and accuracy depend on another service, making them unsuitable for essential project information.
- Repository-hosted images are versioned with the project, but links to a branch can change while links to a commit are immutable and harder to maintain.
- Large screenshots slow repository pages and clones when committed directly, so dimensions, compression, update frequency, and storage location should be considered.
- Dark and light GitHub themes can make transparent logos or diagrams unreadable; picture source media queries can provide theme-specific artwork where supported.
A practical approach
- 1
Choose asset ownership and lifetime before selecting the Markdown URL.
- 2
Resize screenshots to their useful reading width and optimize without blurring text.
- 3
Write concise alt text and use a descriptive filename.
- 4
Preview the README in GitHub’s renderer and verify links from forks and package mirrors.
Architecture boundary
GitHub controls README rendering and repository permissions. Image-processing tools can prepare files before they are committed or linked, but they do not upload into Git history or manage GitHub attachments.
Frequently asked questions
Should README images use relative or absolute URLs?
Use relative paths for files versioned with the repository because they normally follow branches and forks. Use an absolute HTTPS URL when another system intentionally owns the asset. Test either form in every important renderer, since package sites and copied Markdown may resolve paths differently.
Can a README image be resized with Markdown?
Basic Markdown does not provide a portable sizing syntax. Use a simple HTML img element with width and height when sizing is necessary, then preview it on GitHub. Optimize the source file as well, because display dimensions do not reduce downloaded bytes.
Is embedding an image as base64 a good way to avoid broken links?
Usually not. Base64 makes the README harder to read and review, increases its text size, reduces caching flexibility, and may be rejected by some renderers. A tracked image file or deliberately managed public URL is easier to maintain.
Are externally hosted README images safe for private repositories?
Do not assume so. The image host may receive requests from readers, and a public URL can expose an asset independently of repository permissions. Avoid confidential content, use an approved host, and understand GitHub's current image handling before embedding third-party resources.
How should screenshots containing account data be handled?
Capture a dedicated test account when possible. Crop unrelated areas, redact tokens and personal information, inspect notifications and browser chrome, and remove sensitive metadata. Treat irreversible blur cautiously because underlying details can sometimes remain recoverable in source files or editing history.