diff --git a/web/src/engine/transformers/BookmarkConverter.ts b/web/src/engine/transformers/BookmarkConverter.ts
index 80debb6c28..ac1d146e14 100644
--- a/web/src/engine/transformers/BookmarkConverter.ts
+++ b/web/src/engine/transformers/BookmarkConverter.ts
@@ -7,9 +7,10 @@ import type { BookmarkSerialized } from '../providers/Bookmark';
  * @remarks Only exported for testing
  */
 export const legacyWebsiteIdentifierMap = new Map([
+    [ 'allanimesite', 'allmangato' ],
+    [ 'apolltoons', 'mundomanhwa' ],
     [ 'aresnov', 'scarmanga' ],
     [ 'azoramanga', 'azoraworld' ],
-    [ 'apolltoons', 'mundomanhwa' ],
     [ 'bacamangaorg', 'bacamanga' ],
     [ 'bananascan', 'harmonyscan' ],
     [ 'blogtruyen', 'blogtruyenmoi' ],
diff --git a/web/src/engine/transformers/BookmarkConverter_test.ts b/web/src/engine/transformers/BookmarkConverter_test.ts
index ce8ce4159a..70fcd16bd1 100644
--- a/web/src/engine/transformers/BookmarkConverter_test.ts
+++ b/web/src/engine/transformers/BookmarkConverter_test.ts
@@ -9,8 +9,9 @@ import { Key } from '../SettingsGlobal';
 import { GetLocale } from '../../i18n/Localization';
 
 const legacyWebsiteIdentifierMapTestCases = [
-    { sourceID: 'aresnov', targetID: 'scarmanga' },
+    { sourceID: 'allanimesite', targetID: 'allmangato' },
     { sourceID: 'apolltoons', targetID: 'mundomanhwa' },
+    { sourceID: 'aresnov', targetID: 'scarmanga' },
     { sourceID: 'azoramanga', targetID: 'azoraworld' },
     { sourceID: 'bacamangaorg', targetID: 'bacamanga' },
     { sourceID: 'bananascan', targetID: 'harmonyscan' },
diff --git a/web/src/engine/websites/AllMangaTo.ts b/web/src/engine/websites/AllMangaTo.ts
new file mode 100644
index 0000000000..0d63fa9900
--- /dev/null
+++ b/web/src/engine/websites/AllMangaTo.ts
@@ -0,0 +1,148 @@
+import { Tags } from '../Tags';
+import icon from './AllMangaTo.webp';
+import { Chapter, Page } from '../providers/MangaPlugin';
+import { DecoratableMangaScraper, Manga, type MangaPlugin } from '../providers/MangaPlugin';
+import * as Common from './decorators/Common';
+import { FetchCSS, FetchJSON } from '../platform/FetchProvider';
+
+type GraphQLResult<T> = {
+    data: T
+};
+
+type APIMangas = {
+    mangas: {
+        edges: APIManga[],
+    }
+}
+
+type APIManga = {
+    _id: string,
+    englishName: string | null,
+    name: string,
+    availableChaptersDetail: Record<string, string[]>
+}
+
+type APIChapters = {
+    manga: APIManga
+}
+
+type ChapterID = {
+    id: string,
+    translation: string
+}
+
+type APIPages = {
+    chapterPages: {
+        edges: {
+            pictureUrlHead: string,
+            pictureUrls: {
+                url: string
+            }[]
+        }[]
+    }
+}
+
+@Common.ImageAjax()
+export default class extends DecoratableMangaScraper {
+
+    private readonly apiUrl = 'https://api.allanime.day/api';
+
+    public constructor() {
+        super('allmangato', `AllManga.to`, 'https://allmanga.to', Tags.Media.Manga, Tags.Media.Manhua, Tags.Media.Manhwa, Tags.Language.Multilingual, Tags.Source.Aggregator);
+    }
+
+    public override get Icon() {
+        return icon;
+    }
+
+    public override ValidateMangaURL(url: string): boolean {
+        return new RegExpSafe(`^${this.URI.origin}/manga/[^/]+/[^/]+$`).test(url);
+    }
+
+    public override async FetchManga(provider: MangaPlugin, url: string): Promise<Manga> {
+        const title = (await FetchCSS(new Request(new URL(url)), 'ol.breadcrumb li:last-of-type')).shift().textContent.trim();
+        return new Manga(this, provider, url.match(/\/manga\/([^/]+)\//)[1], title);
+    }
+
+    public override async FetchMangas(provider: MangaPlugin): Promise<Manga[]> {
+        const mangaList: Manga[] = [];
+        for (let page = 1, run = true; run; page++) {
+            await new Promise(resolve => setTimeout(resolve, 200));
+            const mangas = await this.GetMangasFromPage(page, provider);
+            mangas.length > 0 ? mangaList.push(...mangas) : run = false;
+        }
+        return mangaList;
+    }
+
+    private async GetMangasFromPage(page: number, provider: MangaPlugin): Promise<Manga[]> {
+        const jsonVariables = {
+            search: {
+                isManga: true,
+                allowAdult: true,
+                allowUnknown: true
+            },
+            limit: 26, //impossible to change
+            page: page,
+            translationType: 'sub',
+            countryOrigin: 'ALL'
+        };
+        const jsonExtensions = {
+            persistedQuery: {
+                version: 1,
+                sha256Hash: 'a27e57ef5de5bae714db701fb7b5cf57e13d57938fc6256f7d5c70a975d11f3d'
+            }
+        };
+
+        const data = await this.FetchGraphQL<APIMangas>(jsonVariables, jsonExtensions);
+        return data?.mangas?.edges ? data.mangas.edges.map(manga => new Manga(this, provider, manga._id, manga.englishName ?? manga.name)) : [];
+    }
+
+    public override async FetchChapters(manga: Manga): Promise<Chapter[]> {
+        const jsonVariables = {
+            _id: manga.Identifier,
+        };
+        const jsonExtensions = {
+            persistedQuery: {
+                version: 1,
+                sha256Hash: 'a42e1106694628f5e4eaecd8d7ce0c73895a22a3c905c29836e2c220cf26e55f'
+            }
+        };
+        const { manga: { availableChaptersDetail } } = await this.FetchGraphQL<APIChapters>(jsonVariables, jsonExtensions);
+        return Object.keys(availableChaptersDetail).reduce((accumulator: Chapter[], key) => {
+            const chapters = availableChaptersDetail[key].map(chapter => new Chapter(this, manga, JSON.stringify({ id: chapter, translation: key }), `Chapter ${chapter} [${key}]`));
+            accumulator.push(...chapters);
+            return accumulator;
+        }, []);
+    }
+
+    public override async FetchPages(chapter: Chapter): Promise<Page[]> {
+        const { id, translation }: ChapterID = JSON.parse(chapter.Identifier);
+        const jsonVariables = {
+            mangaId: chapter.Parent.Identifier,
+            translationType: translation,
+            chapterString: id,
+            limit: 10,
+            offset: 0
+        };
+        const jsonExtensions = {
+            persistedQuery: {
+                version: 1,
+                sha256Hash: '121996b57011b69386b65ca8fc9e202046fc20bf68b8c8128de0d0e92a681195'
+            }
+        };
+        const { chapterPages: { edges } } = await this.FetchGraphQL<APIPages>(jsonVariables, jsonExtensions);
+        const source = edges.find(source => source.pictureUrlHead);
+        return source.pictureUrls.map(picture => new Page(this, chapter, new URL(picture.url, source.pictureUrlHead)));
+    }
+
+    private async FetchGraphQL<T extends JSONElement>(variables: JSONObject, extensions: JSONObject): Promise<T> {
+        const url = new URL(`?variables=${JSON.stringify(variables)}&extensions=${JSON.stringify(extensions)}`, this.apiUrl);
+        const { data } = await FetchJSON<GraphQLResult<T>>(new Request(url, {
+            headers: {
+                Origin: this.URI.origin
+            }
+        }));
+        return data;
+    }
+
+}
\ No newline at end of file
diff --git a/web/src/engine/websites/AllMangaTo.webp b/web/src/engine/websites/AllMangaTo.webp
new file mode 100644
index 0000000000..73d8c641bb
Binary files /dev/null and b/web/src/engine/websites/AllMangaTo.webp differ
diff --git a/web/src/engine/websites/AllMangaTo_e2e.ts b/web/src/engine/websites/AllMangaTo_e2e.ts
new file mode 100644
index 0000000000..3aa395b181
--- /dev/null
+++ b/web/src/engine/websites/AllMangaTo_e2e.ts
@@ -0,0 +1,24 @@
+import { TestFixture } from '../../../test/WebsitesFixture';
+
+const config = {
+    plugin: {
+        id: 'allmangato',
+        title: 'AllManga.to'
+    },
+    container: {
+        url: 'https://allmanga.to/manga/kFvrdRcbubPjrhr63/yuan-zun',
+        id: 'kFvrdRcbubPjrhr63',
+        title: 'Yuan Zun'
+    },
+    child: {
+        id: JSON.stringify({id: '643.5', translation: 'sub'}),
+        title: 'Chapter 643.5 [sub]'
+    },
+    entry: {
+        index: 0,
+        size: 714_974,
+        type: 'image/jpeg'
+    }
+};
+
+new TestFixture(config).AssertWebsite();
\ No newline at end of file
diff --git a/web/src/engine/websites/_index.ts b/web/src/engine/websites/_index.ts
index 9f72c71025..fb069213ef 100755
--- a/web/src/engine/websites/_index.ts
+++ b/web/src/engine/websites/_index.ts
@@ -6,6 +6,7 @@ export { default as AGS } from './AGS';
 export { default as Ainzscans } from './Ainzscans';
 export { default as Akuma } from './Akuma';
 export { default as AllHentai } from './AllHentai';
+export { default as AllMangaTo } from './AllMangaTo';
 export { default as AllPornComic } from './AllPornComic';
 export { default as Alphapolis } from './Alphapolis';
 export { default as AmuyScan } from './AmuyScan';