Recently rome was archived and replaced by biome.

Current

Now that lazyvim moved to the community-maintained fork none-ls.nvim, it got much simpler to use biome as a formatter.

~/.config/nvim/lua/plugins/lsp.lua

return {
	{
		"neovim/nvim-lspconfig",
		opts = {
			--- other options
			servers = {
				tsserver = {
					on_attach = function(client)
						-- this is important, otherwise tsserver will format ts/js
						-- files which we *really* don't want.
						client.server_capabilities.documentFormattingProvider = false
					end,
				},
				biome = {},
				-- other language servers
			},
		},
	},
	{
		"jose-elias-alvarez/null-ls.nvim",
		opts = function(_, opts)
			local nls = require("null-ls").builtins
			opts.sources = vim.list_extend(opts.sources or {}, {
				nls.formatting.biome,

				-- or if you like to live dangerously like me:
				nls.formatting.biome.with({
					args = {
						'check',
						'--apply-unsafe',
						'--formatter-enabled=true',
						'--organize-imports-enabled=true',
						'--skip-errors',
						'$FILENAME',
					},
				}),
			})
		end,
	},
}

Updated biome.json

{
	"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
	"organizeImports": {
		"enabled": true
	},
	"formatter": {
		"enabled": true,
		"formatWithErrors": true,
		"indentStyle": "tab",
		"indentSize": 4,
		"lineWidth": 140
	},
	"javascript": {
		"formatter": {
			"quoteStyle": "single",
			"jsxQuoteStyle": "single"
		},
		"globals": ["__DEV__"]
	},
	"linter": {
		"enabled": true,
		"ignore": ["node_modules"],
		"rules": {
			"all": true,
			"complexity": {
				"noUselessFragments": "off"
			},
			"style": {
				"useSingleVarDeclarator": "off",
				"noParameterAssign": "off",
				"noNonNullAssertion": "off"
			},
			"suspicious": {
				"noExplicitAny": "off"
			},
			"nursery": {
				"all": false
			}
		}
	}
}

Original Post

However since lazyvim starter uses null-ls which also have been archived, it’s gotten tricky to get it to use biome by default.

So after a bit of tinkering I got it working.

TL;DR:

~/.config/nvim/lua/plugins/lsp.lua

return {
	{
		"neovim/nvim-lspconfig",
		opts = {
			--- other options
			servers = {
				tsserver = {
					on_attach = function(client)
						-- this is important, otherwise tsserver will format ts/js
						-- files which we *really* don't want.
						client.server_capabilities.documentFormattingProvider = false
					end,
				},
				biome = {},
				-- other language servers
			},
		},
	},
	{
		"jose-elias-alvarez/null-ls.nvim",
		opts = function(_, opts)
			local biome = require("null-ls").builtins.formatting.rome.with({
				command = "biome",
			})
			opts.sources = vim.list_extend(opts.sources or {}, {
				biome
			})
		end,
	},
}

biome.json

{
	"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
	"organizeImports": {
		"enabled": true
	},
	"formatter": {
		"enabled": true,
		"formatWithErrors": true,
		"indentStyle": "tab",
		"indentSize": 4,
		"lineWidth": 120
	},
	"javascript": {
		"formatter": {
			"quoteStyle": "single",
			"jsxQuoteStyle": "single"
		},
		"globals": [
			"__DEV__"
		]
	},
	"linter": {
		"enabled": true,
		"ignore": [
			"node_modules"
		],
		"rules": {
			"all": true,
			"complexity": {
				"noUselessFragments": "off"
			},
			"style": {
				"useSingleVarDeclarator": "off",
				"noParameterAssign": "off",
				"noNonNullAssertion": "off"
			},
			"suspicious": {
				"noExplicitAny": "off"
			},
			"nursery": {
				"noSelfAssign": "error"
			}
		}
	}
}