Free map tiles for your websites and apps Fast. Free. Forever.

Unlimited vector map tiles built from OpenStreetMap data, ready to drop into MapLibre GL or Leaflet. No API key, no quota, no surprise invoice.

Powered by OpenFreeMap 🚀

Why map tiles get expensive (and why LFMaps doesn’t)

Most map tile providers welcome you with free credits. Then traffic grows, and usage-based billing turns a small experiment into a real bill — opaque meters, charges that scale with every map load, and pricing pages you need a spreadsheet for. Google Maps and Mapbox both work this way. What felt free becomes a cost your project may not want.

LFMaps is different. Free means free — no surprises, no caps, no invoices.

Why choose LFMaps for free map tiles?

What you need to ship a map. Nothing you don’t.

No API key required

Drop the tile URL in and go. No signup, no access token, no dashboard.

Unlimited tile requests

No quotas, no soft limits, no per-map-load meter. Use what you need.

Free forever

Zero cost at any traffic level — ten map views or ten million.

No tracking, no data collection

We don’t track your visitors and set no cookies. Your privacy policy stays as short as it was.

Live vector tile demo — three map styles

How to add free map tiles to your site

Works best with MapLibre GL, and with Leaflet or React too

Step 1: Add MapLibre GL to your HTML

<script src="https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css" rel="stylesheet" />

MapLibre GL v6 is ESM-only, so these examples pin v5 for drop-in script tag use.

Or install with npm

npm i maplibre-gl@^5

Then import it in your JavaScript:

import maplibregl from 'maplibre-gl'
import 'maplibre-gl/dist/maplibre-gl.css'

Step 2: Create your map

<div id="map" style="width: 100%; height: 500px"></div>
<script>
  const map = new maplibregl.Map({
    style: 'https://data.lfmaps.fr/styles/bright',
    center: [6.1844, 48.6937],
    zoom: 12,
    container: 'map',
  })
</script>

Pro tip: lazy-load MapLibre for better Core Web Vitals

Recommended

Why it helps:

Improves Largest Contentful Paint (LCP)
Reduces First Input Delay (FID)
Keeps Cumulative Layout Shift (CLS) in check
Saves ~750KB on first load

Better Core Web Vitals often mean better search rankings

Use this loader for a leaner first paint:

let maplibrePromise = null;
let cssLoaded = false;

/**
 * Lazily loads MapLibre GL and its CSS when needed
 * @returns {Promise} The MapLibre GL module
 */
async function loadMapLibre() {
    if (!maplibrePromise) {
        maplibrePromise = Promise.all([
            import('maplibre-gl'),
            loadMapLibreCSS()
        ]).then(([module]) => module.default);
    }
    return maplibrePromise;
}

/**
 * Loads MapLibre GL CSS dynamically
 */
async function loadMapLibreCSS() {
    if (!cssLoaded) {
        await import('maplibre-gl/dist/maplibre-gl.css');
        cssLoaded = true;
    }
}

/**
 * MapLibre GL Lazy Loader Class
 * Provides an API similar to maplibregl but with lazy loading
 */
export class MapLibreLoader {
    constructor() {
        this.maplibregl = null;
    }

    /**
     * Creates a new map instance, lazily loading MapLibre GL if needed
     * @param {Object} options - Map configuration options
     * @returns {Promise} A MapLibre GL Map instance
     */
    async createMap(options) {
        this.maplibregl = await loadMapLibre();
        return new this.maplibregl.Map(options);
    }

    /**
     * Gets the MapLibre GL library, lazily loading if needed
     * @returns {Promise} The MapLibre GL library
     */
    async getLibrary() {
        this.maplibregl = await loadMapLibre();
        return this.maplibregl;
    }
}

export default new MapLibreLoader();

Usage example:

import MapLibreLoader from './maplibre-loader.js';

// Create map only when needed (e.g., on scroll or user interaction)
async function initMap() {
    const map = await MapLibreLoader.createMap({
        style: 'https://data.lfmaps.fr/styles/bright',
        center: [6.1844, 48.6937],
        zoom: 12,
        container: 'map',
    });
    
    // Add controls, markers, etc.
    const maplibregl = await MapLibreLoader.getLibrary();
    map.addControl(new maplibregl.NavigationControl());
}

For advanced features and the full API, see the MapLibre GL JS documentation

Using Leaflet instead? Add free tiles with one plugin

Leaflet can’t read vector tiles on its own, so pair it with the maplibre-gl-leaflet plugin:

<link href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" rel="stylesheet" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js"></script>
<script src="https://unpkg.com/@maplibre/maplibre-gl-leaflet@0.1.3/leaflet-maplibre-gl.js"></script>

<script>
  const map = L.map('map').setView([48.6937, 6.1844], 12)
  L.maplibreGL({
    style: 'https://data.lfmaps.fr/styles/bright',
  }).addTo(map)
</script>

Leaflet 1.x is what the plugin supports — the same free tiles, none of the billing.

Free map tiles in React

npm i react-map-gl maplibre-gl@^5
import Map from 'react-map-gl/maplibre'
import 'maplibre-gl/dist/maplibre-gl.css'

export default function MyMap() {
  return (
    <Map
      initialViewState={{ longitude: 6.1844, latitude: 48.6937, zoom: 12 }}
      style={{ width: '100%', height: 500 }}
      mapStyle="https://data.lfmaps.fr/styles/bright"
    />
  )
}

No mapbox-gl, no access token — react-map-gl talks to MapLibre GL directly.

Free map tile styles: bright, positron and liberty

  • https://data.lfmaps.fr/styles/bright
  • https://data.lfmaps.fr/styles/positron
  • https://data.lfmaps.fr/styles/liberty

Built for speed: fast tile delivery worldwide

Lightning fast

Tiles served from a CDN, so maps appear in a blink

Reliable

99.9% uptime

Global coverage

OpenStreetMap data covering the whole world

Easy to integrate

A few lines of MapLibre GL or Leaflet and you’re live

A free alternative to Google Maps and Mapbox

Same job — a map on your page. Very different bill at the end of the month.

Paid map tile providers

  • A free tier, then billing per map load once you outgrow it
  • An API key to create, secure and rotate
  • Usage dashboards, quotas and billing alerts to watch
  • Analytics collected on the people using your map

LFMaps

  • Free at every traffic level — there is no meter to outgrow
  • No API key, because there is no account
  • Nothing to monitor: paste a style URL and move on
  • No tracking of you or of your visitors

The honest trade-off: LFMaps gives you map tiles and nothing else. Geocoding, routing and turn-by-turn directions are not part of the service.

Free map tiles: frequently asked questions

Is LFMaps really free?

Yes. There is no paid tier, no credit card, and no usage bill — whatever your traffic. LFMaps is funded as a side project, the way the other free tools on this page are.

Do I need an API key or an account?

No. There is nothing to sign up for and no token to rotate. Point your map style at a LFMaps URL and it works.

Are there rate limits or quotas on map tiles?

No quotas and no hard rate limit. We only ask that you don’t bulk-scrape the whole tile set — normal map usage on a website or app is fine.

Does LFMaps work with Leaflet as well as MapLibre GL?

Yes. MapLibre GL renders the vector tiles natively and is what we recommend, but Leaflet works too with the maplibre-gl-leaflet plugin.

Where does the map data come from?

From OpenStreetMap, served through OpenFreeMap. The data is community made, which is exactly why it can stay free.

Can I use LFMaps on a commercial website?

Yes, commercial projects included. Keep the OpenStreetMap attribution visible on the map — that’s the only requirement.

Do you track my visitors?

No. We collect no personal data and set no cookies on the tile requests, so adding a map doesn’t add anything to your privacy policy.

How is this different from Google Maps or Mapbox?

Those give you a free tier and then bill per map load once you grow. LFMaps has no meter at all: the price is zero at ten map views and at ten million.