Back to Blog
githubreadmemarkdowndocumentationopen-source

How to Add Images to a GitHub README (2026 Guide)

Learn how to add images to a GitHub README — five embed methods, sizing, dark mode, and the gotchas that break images on npm and forks.

Gautam Sharma, Founder Dokly

Author

13 min read

TL;DR

  • Use ![alt](path/to/image.png) for the basic case. Drag and drop into the GitHub web editor for the fastest workflow.
  • Markdown can't resize images — use <img src="..." width="300" /> instead. GitHub allows it.
  • For dark mode, use <picture> with prefers-color-scheme media queries.
  • Use relative paths for portability. Switch to raw.githubusercontent.com URLs only when the README ships to npm.
  • Most "image not loading" bugs are blob URLs that should be raw URLs.

To add an image to a GitHub README, use the markdown syntax ![alt text](path/to/image.png). The path can be relative to the repo, an absolute raw URL, or a link to any external host. That's the answer in one line. The reason this post is 2,000 words is that the one-liner breaks the moment you need a logo at a specific width, a screenshot that swaps with dark mode, or a README that survives being published to npm.

Here's the full reference.

The fastest way: drag and drop#

If you're editing a README on github.com, drag the image file directly into the editor. GitHub uploads it to user-images.githubusercontent.com (its CDN for issue attachments and README assets) and inserts a working markdown image tag at your cursor.

Markdown
![Screenshot 2026-04-12 at 10.42](https://user-images.githubusercontent.com/12345/abc123.png)

It takes about two seconds. The downside: the image isn't in your repo. If GitHub ever changes that CDN, or if someone forks your project, the image still loads (the URL is permanent for now), but you don't own the asset. For a one-off screenshot in an issue or a quick patch, drag-and-drop is fine. For your project's logo or hero image, commit the file to the repo instead.

Pro tip

Drag-and-drop also works in pull request descriptions and issue comments. Use it for bug-report screenshots — much faster than uploading to Imgur.

The five ways to add an image to a README#

There are exactly five places a README image can live. Each has a use case where it's the right call and at least one situation where it breaks.

MethodExamplePortableWorks on npmWorks on forks
Relative pathimages/logo.pngYesNoYes
Absolute repo URLhttps://github.com/user/repo/blob/main/logo.png?raw=trueNoYesNo (broken on rename)
Raw URLhttps://raw.githubusercontent.com/user/repo/main/logo.pngNoYesNo (broken on rename)
Drag-and-drop CDNhttps://user-images.githubusercontent.com/...NoYesYes
External hosthttps://cdn.example.com/logo.pngNoYesYes

A few things this table makes clear. Relative paths win on portability — they work on GitHub, GitLab mirrors, Gitea, Bitbucket, and most static-site generators that consume your README. They break only when the README is detached from the repo (e.g. published to npm).

Raw URLs win when the README ships outside the repo. If you publish to npm, the registry shows your README on the package page but doesn't have access to your repo's files. Relative paths break. Absolute raw URLs work — but they're tied to your username, repo name, and branch. Rename any of those and every image is dead.

Drag-and-drop is for transient stuff. It's hosted on GitHub's CDN forever (in practice), but it's not in your repo, so you can't migrate it elsewhere.

Step-by-step: add an image using a relative path#

This is the method to default to. It's portable, version-controlled, and survives forks.

Create an images folder

In your repo root, create a folder called images/ or assets/ or docs/images/ — whatever convention you like. The folder name doesn't matter, but pick one and stick to it.

Bash
mkdir images

Add the image file

Drop your image into the folder. Use a kebab-case filename without spaces.

Bash
cp ~/Downloads/logo.png images/logo.png

Commit and push

The image must exist on the branch your README renders from (usually main).

Bash
git add images/logo.png
git commit -m "Add logo image"
git push origin main

Reference it from README.md

Use the markdown image syntax with a path relative to the README file's location.

Markdown
![Project logo](images/logo.png)

If your README is in the repo root and your image is in /images/logo.png, the relative path is images/logo.png. No leading slash. No ./ needed (though it works).

Verify on GitHub

Open the README on github.com. The image should render inline. If it doesn't, see the troubleshooting section below.

That's the github readme image syntax most projects should default to. It's also what every major open-source project does — check the React, Vue, or Next.js repos.

How to resize images in a GitHub README#

The github readme markdown image size problem is the single most common follow-up question. Markdown's image syntax — ![alt](src) — has no width or height parameter. The GFM spec is clear about this: the GitHub Flavored Markdown spec doesn't extend the image syntax beyond CommonMark.

The fix: drop into HTML.

HTML
<img src="images/logo.png" alt="Project logo" width="300" />

GitHub renders a sanitized subset of HTML inside markdown files. The <img> tag is allowed, and the width and height attributes are preserved. You can use either or both — if you set only width, the image scales proportionally.

HTML
<img src="images/screenshot.png" alt="Dashboard screenshot" width="600" />

What GitHub strips:

  • style= attributes (no inline CSS)
  • class= attributes (no external stylesheets either)
  • <script> and event handlers
  • Most other HTML tags beyond a small allowlist

So you can't write <img style="width: 50%">. You have to use the attribute. Pixel values only — percentages don't work reliably across GitHub's renderers.

Don't put <img> tags on the same line as markdown text without a blank line separator. The renderer sometimes treats them as inline and the rendering gets weird. Put HTML blocks on their own lines.

For a logo at the top of a README, 200-400px wide is the sweet spot. For inline screenshots, 600-800px. For full-width hero images, leave the width off and let it render at native resolution.

How to add light and dark mode images#

GitHub readers see READMEs in either light or dark mode based on their account preference. A logo that's black-on-white looks great in light mode and disappears in dark mode. The fix is the HTML <picture> element.

HTML
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="images/logo-dark.png">
  <source media="(prefers-color-scheme: light)" srcset="images/logo-light.png">
  <img alt="Project logo" src="images/logo-light.png">
</picture>

The browser picks the matching <source> based on the user's color scheme. If neither matches (rare), it falls back to the <img> tag. This is the official method documented in GitHub's documentation on theme-aware images.

Two things to know:

  1. The media attribute uses standard CSS media queries. prefers-color-scheme on MDN is the spec.
  2. You can combine <picture> with <img width="..."> for sizing. Put the width on the fallback <img>.
HTML
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="images/logo-dark.png">
  <img alt="Project logo" src="images/logo-light.png" width="240">
</picture>

The MDN reference on the picture element covers the full element semantics if you want to do responsive image swaps too — though GitHub's use case is almost always just the dark-mode toggle.

For SVG logos, use two SVG files (one with white strokes, one with black) rather than trying to use CSS currentColor — GitHub strips the styles that would make currentColor work.

How to center, align, and caption images#

Markdown has no concept of alignment. To center an image in a README, wrap it in a <div> or <p> with an align attribute.

HTML
<p align="center">
  <img src="images/logo.png" alt="Project logo" width="300" />
</p>

align="center" is technically deprecated HTML, but GitHub's renderer still respects it on <p> and <div> tags. It's how every popular project centers their logo. You can also use align="left" or align="right" to float images.

For captions, markdown doesn't have a native syntax. The closest you can get is alt text plus a line of italic text underneath:

Markdown
![Architecture diagram](images/architecture.png)
 
*Figure 1. Request flow from client to database.*

Some projects use <figure> and <figcaption> — GitHub strips those. Stick with the alt-text-plus-italics convention.

To add a logo to a GitHub README at the top, the standard pattern looks like this:

HTML
<p align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="images/logo-dark.svg">
    <img alt="Project name" src="images/logo-light.svg" width="280">
  </picture>
</p>
 
<h1 align="center">Project Name</h1>
 
<p align="center">
  One-line description of what this project does.
</p>

Centered logo, theme-aware, sized correctly, with a centered title and tagline. That's what every well-designed README opens with.

Common errors and how to fix them#

These are the failure modes I've seen come up over and over in issue trackers and Stack Overflow.

Image works in the repo but breaks on npm#

Symptom: your README looks fine on github.com but shows broken image icons on npmjs.com.

Cause: relative paths. npm doesn't have your repo's files — it only has what you published in the package tarball.

Fix: switch to absolute raw URLs for any image you want to show on npm.

Markdown
![Logo](https://raw.githubusercontent.com/user/repo/main/images/logo.png)

Or include the images folder in your published package by adding it to the files field in package.json — but the URLs still need to resolve, which usually means absolute. This trips up almost everyone the first time. Our open source documentation best practices post goes deeper on the npm-vs-GitHub README split.

Symptom: the image doesn't render. Clicking the link takes you to a GitHub page that contains the image, not the image itself.

Cause: blob URLs.

Markdown
<!-- BROKEN -->
![Logo](https://github.com/user/repo/blob/main/images/logo.png)

The URL github.com/user/repo/blob/main/... returns HTML, not the raw image. Markdown image syntax expects an image MIME type, so the renderer gives up.

Fix: use the raw URL or append ?raw=true.

Markdown
![Logo](https://raw.githubusercontent.com/user/repo/main/images/logo.png)

Image breaks after renaming the repo or default branch#

Cause: absolute URLs hard-code the username, repo name, and branch. Change any of them and the URL 404s.

Fix: use relative paths whenever you can. They survive renames and branch swaps.

"File too large" when dragging into the editor#

GitHub's drag-and-drop has a 10 MB per-file limit. For larger images:

  • Compress (TinyPNG, Squoosh, or cwebp -q 80)
  • Convert to WebP — GitHub renders WebP, and it's typically 30-50% smaller than PNG
  • For animated demos, prefer MP4 over GIF — GitHub allows MP4 in issues and renders inline

Image takes forever to load#

Large PNG screenshots are the usual culprit. A 4K screenshot can be 5+ MB. Resize to display dimensions before committing — a logo at 240px wide doesn't need a 2,000px source.

Bash
# Quick resize with ImageMagick
magick logo-original.png -resize 480x logo.png

Display at 240px, ship at 480px (for retina). That's the rule.

When your README outgrows itself#

A README is great for one screen of context. Once you have install instructions, an API reference, contributor guides, architecture diagrams, and a changelog all in one file, the README stops being readable. Long READMEs don't get read.

The signs you've outgrown it:

  • The table of contents is longer than the first section
  • People keep filing issues asking questions answered in the README
  • You have multiple docs/*.md files and they don't cross-link well
  • You want search, versioning, or analytics

At that point, your README should become a landing page that links to real docs. Static-site generators like Docusaurus and MkDocs work, though both require a build pipeline and Git workflow. Hosted platforms — Dokly's visual MDX editor is what we build — give you the same result without managing CI or fighting with frontmatter.

If you want to see the full path from "great README" to "real docs site", we wrote a step-by-step guide to building developer docs in minutes that walks through the transition. Combined with our guide to writing a README that gets your project starred, you'll have both halves of the story covered.

Frequently Asked Questions#

How do I add an image to a GitHub README?#

Use the markdown image syntax: ![alt text](path/to/image.png). The path can be a relative path inside your repo (like images/logo.png), an absolute URL to the raw file on GitHub, or any external image URL. The simplest method is to drag and drop the image directly into the README editor on github.com — GitHub uploads it and inserts the markdown for you.

Why is my image not showing up in my README?#

The most common cause is using a blob URL instead of a raw URL. GitHub's blob URLs (github.com/user/repo/blob/main/image.png) point to an HTML page that displays the image, not the image itself. Use the raw URL (raw.githubusercontent.com/user/repo/main/image.png) or a relative path like ./image.png. Also check the file is actually committed and pushed to the branch your README is rendering from.

How do I resize an image in a GitHub README?#

Markdown image syntax doesn't support width or height, so you need to use an HTML <img> tag instead: <img src="image.png" width="300" />. GitHub renders a safe subset of HTML in markdown files, and the width and height attributes are allowed. CSS styles in style= attributes are stripped, so stick to attributes.

Can I have different images for light and dark mode?#

Yes. GitHub supports the HTML <picture> element with prefers-color-scheme media queries. Provide a <source> for dark mode, a <source> for light mode, and a fallback <img>. The browser picks the right one based on the viewer's GitHub theme. This is the official method GitHub recommends for theme-aware images.

Should I use relative paths or absolute URLs for README images?#

Relative paths (like images/logo.png) are the most portable — they work on GitHub, GitLab mirrors, and most documentation generators. Absolute URLs to raw.githubusercontent.com break if you rename the repo or change the default branch. The exception: if your README is published to npm or another package registry, relative paths break because the registry doesn't have the image. In that case, use absolute raw URLs.

What image formats does GitHub README support?#

GitHub's markdown renderer supports PNG, JPG, GIF, SVG, and WebP. SVG works for logos and diagrams but is sandboxed — scripts inside SVGs are stripped. Animated GIFs play automatically. There's a 10 MB per-file limit when uploading via drag and drop, and the rendered README has a soft size limit before GitHub truncates it.

Where to go from here#

If your README has grown into something that needs search, versioning, and a real navigation tree, you can start a free Dokly project and have a docs site live in a few minutes — no Git workflow, no build pipeline, just a visual editor. Or see Dokly's pricing first.

Written by Gautam Sharma, Founder Dokly

Building Dokly — documentation that doesn't cost a fortune.

Follow on Twitter →

Ready to build better docs?

Start creating beautiful documentation with Dokly today.

Get Started Free