Skip to content

Instantly share code, notes, and snippets.

@bitbybit
Created January 16, 2025 16:15
Show Gist options
  • Select an option

  • Save bitbybit/6badd08ffc66dc449d0d3bfcb7009806 to your computer and use it in GitHub Desktop.

Select an option

Save bitbybit/6badd08ffc66dc449d0d3bfcb7009806 to your computer and use it in GitHub Desktop.
How to import history from Orion Browser by Kagi to any other browser

While Orion does not provide a direct way to export history entries, it is possible to manually copy them from the "Show History" window. To do this, expand the date groups, select all the lines, and copy them. The output will look like this:

2024-01-16 00:00:00 Orion Browser by Kagi https://kagi.com/orion

You can paste this output into a plain text file to proceed with the next steps.

Firefox has an add-on called History-Export that enables history export and import. To use it with Orion's history, you need to convert the copied entries into a format supported by this add-on. Update the variables pathToHistoryFile and pathToNewImportFile in the provided script, then run:

tsc && node ./dist/index.js

Once converted, the history can be imported from Firefox into any Chromium-based browser (e.g., Chrome, Brave) or Safari.

Side note

To enable Firefox to import history entries older than its default limits, adjust the following preferences in about:config:

  • browser.migrate.history.limit: 500000
  • browser.migrate.chrome.history.limit: 500000
  • browser.migrate.safari.history.limit: 500000
  • browser.migrate.history.maxAgeInDays: 3650
  • browser.migrate.chrome.history.maxAgeInDays: 3650
  • browser.migrate.safari.history.maxAgeInDays: 3650
import { readFile, writeFile } from 'node:fs/promises';
const pathToHistoryFile = `${import.meta.dirname}/../../history.txt`
const pathToNewImportFile = `${import.meta.dirname}/../../history.json`
type ExportEntry = {
date: Date
title: string
url: string
}
type ImportEntry = {
id: string
url: string
title: string | null
lastVisitTime: number
visitCount: number
}
const rawHistory = await readFile(
pathToHistoryFile,
'utf8'
)
const listHistory = rawHistory.split('\n')
const historyToExportEntry = (historyLine: string): ExportEntry => {
const url = historyLine.split(' ').at(-1) ?? null
if (url === null) {
throw new Error(`No URL: ${historyLine}`)
}
const dateMatch = RegExp(
/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/
).exec(historyLine)
const dateString = dateMatch?.[0] ?? null
if (dateString === null) {
throw new Error(`No date: ${historyLine}`)
}
const date = new Date(dateString)
const title = historyLine.slice(
dateString.length + 1,
historyLine.indexOf(url) - 1
)
return {
date,
title,
url
}
}
const exportEntries = listHistory.map(historyToExportEntry)
const importEntryToExportEntry = ({
entries,
lastId
}: {
entries: ImportEntry[],
lastId: number
}, {
date,
title,
url
}: ExportEntry): {
entries: ImportEntry[],
lastId: number
} => ({
lastId: lastId += 1,
entries: [
...entries,
{
id: String(lastId),
url,
title,
lastVisitTime: date.getTime(),
visitCount: 1
}
]
})
const result = exportEntries.reduce(importEntryToExportEntry, {
lastId: 0,
entries: []
})
await writeFile(pathToNewImportFile, JSON.stringify(result.entries, null, 2))
{
"name": "firefox-import",
"version": "1.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"build": "tsc"
},
"type": "module",
"devDependencies": {
"@types/node": "^22.10.7",
"typescript": "^5.5.3"
},
"private": true
}
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"moduleResolution": "nodenext",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "dist"
},
"include": ["src"],
"exclude": ["node_modules"]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment