✨ We are thrilled to announce that the refine v4 is now officially released! ✨
After a year since the release of v3, we have addressed the most requested and questioned areas by the community. refine v4 features better developer experience, and new functionalities to simplify the work of developers. It has also been designed to make refine accessible on all platforms that support React, and to ensure that it can be seamlessly integrated into new and existing projects.
Throughout the development process, we have carefully analyzed feedback, discussions, and questions raised by the community to enhance the framework. We value ongoing feedback and requests, as they will help us to continue improving and evolving refine.
With 100% backward compatibility, users can rest assured that their applications will continue to function as expected with the latest update.
📒Migration Guide: https://refine.dev/docs/migration-guide/3x-to-4x/
What is new in refine v4? 🔥
- refine v4 includes several new features that are designed to enhance the Developer Experience. We have introduced abstractions and techniques that make it easier for developers to manage concerns such as data management, routing, authorization, layouts, and more, without limiting the functionality of other tools and libraries they may prefer to use.
- One of the best things about v4 is that it provides 100% backward compatibility, so users can update to the latest version with confidence that their applications will continue to function as expected.
- Thanks to full codemod support, the entire upgrade process will be automatically updated when you migrate your refine project to v4.
🪄 Migrating your project automatically with refine-codemod ✨
We are putting an end to the developer effort that would take hours.
As the refine team, we use many open-source projects and we are sensitive to breaking changes and version upgrades, which can be challenging. Therefore, for four versions, we have been managing all changes with codemod, and we are delighted about it!
@refinedev/codemod
package handles the breaking changes for your project automatically, without any manual steps. It migrates your project from 3.x.x
to 4.x.x.
npx @refinedev/codemod@latest refine3-to-refine4
The process is complete, and your project now uses refine@4.x.x. 🚀
Refer to Migration guide for details
New features and improvements🚀
⭐ Bring your own router
- Routes is now completely detached from refine
- We have made significant changes to the routerProvider and route handling to improve flexibility and provide unlimited customization options, in response to requests from our community.
routerProvider
is now optional and you can use refine without a router.- We eliminated the need for a specific way of defining routes by simplifying
routerProvider
to act solely as a link between refine and the router. This allows any router to be used with "refine". - Users can integrate refine into their existing projects without needing to modify their current routes or application structure.
- With its flexible structure, refine now supports React, Remix, Next.js, and Remix platforms, providing a seamless experience for developers. This is also a promising sign that refine will soon provide support for React Native.
⭐ Enterprise-grade routing
- We now offer top-notch support for routes for
resources
. With this new feature, you have complete freedom to create routes that can be tailored to meet the specific needs of your advanced and enterprise use cases. There are no limits or restrictions, so you can create routes that truly fit your unique requirements. - You can define your actions (
list
,create
,edit
,show
,clone
) as paths rather than components. This will allow you to defining custom routes for actions and also using the full potential of your router without being restricted to the routes created automatically.
⭐ Reduced bundle size
- To improve performance and optimize bundle size, we have removed re-exported packages from refine.
- While re-exporting can offer advantages such as allowing packages to be used without being loaded, it can also lead to issues with bundle size.
- In response to feedback from the community, we made this change as bundle size has become increasingly important for React-based frameworks like refine that support various CRUD applications with the help of Remix and Next.js.
- Removing re-exported packages enables you to achieve the same bundle size as a vanilla React project.
⭐ New Auth Provider
- refine v4 introduces a common interface for the authProvider methods to improve transparency for developers and facilitate better understanding and debugging. Previously, developers had to resolve the authProvider methods upon success and reject them upon failure.
- With the latest update, authProvider methods in refine v4 will always return a resolved promise containing an object with a success key. This key indicates whether the operation was successful or not. In case of failure, an optional error key carrying an Error object can be used to notify users.
Refer to AuthProvider Migration Guide for all implemented updates
Changelog 📗
The following refine packages includes component and hook updates. You can view the details on migration guide by clicking to each one.
We'll show some of new features and updates below. You can view the full changelog
@refinedev/core
Updates
Changes in resources
Now you can define actions in multiple ways;
i. As a path
<Refine
resources={[
{
name: "posts",
list: "/posts",
},
]}
>
...
</Refine>
ii. As a component
import { PostList } from "src/posts";
<Refine
resources={[
{
name: "posts",
list: PostList,
},
]}
>
...
</Refine>;
iii. As both
import { PostList } from "src/posts";
<Refine
resources={[
{
name: "posts",
list: {
path: "/posts",
component: PostList,
},
},
]}
>
...
</Refine>;
Nested routes
Now, refine supports nested routes with parameters. You can define the action paths for a resource with parameters. Parameters will be filled with the current ones in the URL and additional ones can be provided via meta properties in hooks and components.
<Refine
resources={[
{
name: "posts",
list: "users/:authorId/posts",
show: "users/:authorId/posts/:id",
},
]}
>
Changes in routerProvider
- routerProvider is now smaller and more flexible. It only contains the following properties;
Link
: A component that accepts to prop and renders a link to the given path.go
: A function that returns a function that accepts a config object and navigates to the given path.back
: A function that returns a function that navigates back to the previous page.parse
: A function that returns a function that returns the resource, id, action and additional params from the given path. This is the refine's way to communicate with the router library.
@refinedev/antd
Updates
meta
property changes in components
It can be used to pass additional parameters to the navigation paths.
For aposts
resource definition like this:
<Refine
resources={[
{
name: "posts",
list: "/posts",
show: "/:authorId/posts/:id",
}
]}
>
You can pass authorId
to the ShowButton
component like this:
<ShowButton resource="posts" id="1" meta={{ authorId: 123 }}>
This will navigate to /123/posts/1
path.
syncWithLocation
support inuseDrawerForm
anduseModalForm
hooksuseTable
return values and properties are updated.
-useSimpleList
hook will not accept all of<List>
component properties
Deprecated Components and Removed props
ignoreAccessControlProvider
prop is removed from buttons.useCheckboxGroup
,useSelect
,useRadioGroup
's'sort
prop is now deprecated. Usesorters
prop instead.useImport
'sresourceName
prop is now deprecated. Useresource
prop instead.<ReadyPage>
is now deprecated.- Deprecated
useMenu
removed from@refinedev/antd
package. UseuseMenu
from@refinedev/core
package instead
Migrating automatically with Codemod
@pankod/refine-codemod
package handles the breaking changes for your project automatically, without any manual steps.
npx @pankod/refine-codemod antd4-to-antd5
And it's done. Now your project uses @pankod/refine-antd@4.x.x
.
@refinedev/mui
Updates
- Updated buttons with
resource
property.resourceNameOrRouteName
is now deprecated but kept working until next major version. - Deprecated
useMenu
removed from@refinedev/mui
package. UseuseMenu
from@refinedev/core
package instead.
Removed props
ignoreAccessControlProvider
prop is removed from buttons.cardProps
,cardHeaderProps
,cardContentProps
,cardActionsProps
andactionButtons
props are removed from CRUD component.useAutocomplete
's sort prop is now deprecated. Usesorters
prop instead.initialCurrent
andinitialPageSize
props are now deprecated. Usepagination
prop instead.
useDataGrid({
- initialCurrent,
- initialPageSize,
+ pagination: {
+ current,
+ pageSize,
+ },
})
- hasPagination
prop is now deprecated. Use
pagination.mode` instead.
useDataGrid({
- hasPagination,
+ pagination: {
+ mode: "off" | "server" | "client",
+ },
})
sorter
andsetSorter
return values are now deprecated. Usesorters
andsetSorters
instead.- All Material UI components re-exported from
@refinedev/mui
have been removed. You should import them from Material UI packages directly.
npm install @mui/material @emotion/react @emotion/styled @mui/lab @mui/x-data-grid
# or
pnpm add @mui/material @emotion/react @emotion/styled @mui/lab @mui/x-data-grid
# or
yarn add @mui/material @emotion/react @emotion/styled @mui/lab @mui/x-data-grid
After that, you can import them from related packages directly.
- import {
- Box,
- NumberField,
- Stack,
- Typography,
- ThemeProvider,
- DataGrid
- LoadingButton,
- } from "@refinedev/mui";
+ import { NumberField } from "@refinedev/mui";
+ import { ThemeProvider } from "@mui/material/styles";
+ import { Box, Stack, Typography } from "@mui/material";
+ import { DataGrid } from "@mui/x-data-grid";
+ import { LoadingButton } from "@mui/lab";
@refinedev/mantine Updates
meta
prop is addedsyncWithLocation
support inuseModalForm
hookignoreAccessControlProvider
prop is removed from buttons.<ReadyPage>
isnow deprecated.- Created a
<WelcomePage>
component to welcome users. - Updated buttons with
resource
property.resourceNameOrRouteName
is now deprecated but kept working until next major version.
@refinedev/chakra-ui Updates
@refinedev/react-table Updates
Minor Changes
-
Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!
All@tanstack/react-table
imports re-exported from@refinedev/react-table
have been removed. You should import them from the@tanstack/react-table
package directly.If the package is not installed, you can install it with your package manager:
npm install @tanstack/react-table
# or
pnpm add @tanstack/react-table
# or
yarn add @tanstack/react-table
After that, you can import them from `@tanstack/react-table` package directly.
- import { useTable, ColumnDef, flexRender } from "@refinedev/react-table";
+ import { useTable } from "@refinedev/react-table";
+ import { ColumnDef, flexRender } from "@tanstack/react-table";
initialCurrent
andinitialPageSize
props are now deprecated. Usepagination
prop instead.
useTable({
- initialCurrent,
- initialPageSize,
+ pagination: {
+ current,
+ pageSize,
+ },
})
- Update type declaration generation with
tsc
instead oftsup
for better navigation throughout projects source code. - Only
or
was supported as a conditional filter. Nowand
andor
can be used together and nested. 🚀
{
operator: "or",
value: [
{
operator: "and",
value: [
{
field: "name",
operator: "eq",
value: "John Doe",
},
{
field: "age",
operator: "eq",
value: 30,
},
],
},
{
operator: "and",
value: [
{
field: "name",
operator: "eq",
value: "JR Doe",
},
{
field: "age",
operator: "eq",
value: 1,
},
],
},
],
}
- Add
hasPagination
property touseTable
hook to enable/disable pagination.useTable
return values and properties are updated.initialCurrent
andinitialPageSize
props are now deprecated. Usepagination
prop instead.- To ensure backward compatibility,
initialCurrent
andinitialPageSize
props will work as before.
useTable({
- initialCurrent,
- initialPageSize,
+ pagination: {
+ current,
+ pageSize,
+ },
})
- `hasPagination` prop is now deprecated. Use `pagination.mode` instead.
- To ensure backward compatibility, `hasPagination` prop will work as before.
useTable({
refineCoreProps: {
- hasPagination,
+ pagination: {
+ mode: "off" | "server" | "client",
+ },
},
})
- `initialSorter` and `permanentSorter` props are now deprecated. Use `sorters.initial` and `sorters.permanent` instead.
- `initialFilter`, `permanentFilter`, and `defaultSetFilterBehavior` props are now deprecated. Use `filters.initial`, `filters.permanent`, and `filters.defaultBehavior` instead.
useTable({
refineCoreProps: {
- initialFilter,
- permanentFilter,
- defaultSetFilterBehavior,
+ filters: {
+ initial,
+ permanent,
+ defaultBehavior,
+ },
},
})
- `sorter` and `setSorter` return values are now deprecated. Use `sorters` and `setSorters` instead.
- To ensure backward compatibility, `sorter` and `setSorter` return values will work as before.
- Add
hasPagination
property touseTable
hook to enable/disable pagination. - Update type declaration generation with
tsc
instead oftsup
for better navigation throughout projects source code.
Patch Changes
- #3399
22b44a857a8
Thanks @yildirayunlu! - FixuseTable
hook error return type. - Fix
@tanstack/react-table
exports - Removed the old version of
react-table
dependency. - #2746
f19369d911
Thanks @omeraplak! - Fix@tanstack/react-table
exports - #2740
8a4a96ac6a
Thanks @salihozdemir! - Removed the old version ofreact-table
dependency. - Fixed type exports for
UseTableProps
andUseTableReturnType
. - #2501
4095a578d4
Thanks @omeraplak! - Fixed version of react-router to6.3.0
@refinedev/react-hook-form
Minor Changes
-
Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!
Allreact-hook-form
imports re-exported from@refinedev/react-hook-form
have been removed. You should import them from thereact-hook-form
package directly.If the package is not installed, you can install it with your package manager:
npm install react-hook-form
# or
pnpm add react-hook-form
# or
yarn add react-hook-form
After that, you can import them from `react-hook-form` package directly.
- import { useForm, Controller } from "@refinedev/react-hook-form";
+ import { useForm } from "@refinedev/react-hook-form";
+ import { Controller } from "react-hook-form";
- Updated the components to match the changes in routing system of
@refinedev/core
.
Patch Changes
- #3307
1262f2c4589
Thanks @omeraplak! - Fixed resetting values on step changes - #3290 - #3209
e0279bce6f1
Thanks @yildirayunlu! - Export all types. - #3196
78b3fd90fcf
Thanks @yildirayunlu! - ExportUseFieldArrayReplace
type fromreact-hook-form
.
@refinedev/react-router-v6
Minor Changes
We're releasing a new way to connect your router to refine.
The legacy routerProvider
and its exports are now deprecated but accessible at @refinedev/react-router-v6/legacy
path.
The new routerBindings
are smaller and more flexible than the previos one.
- #3144
c0aea17837c
Thanks @omeraplak! - Added react-router-dom's exports - #3144
c0aea17837c
Thanks @omeraplak! - Added react-router-dom's exports - #3126
ccaf8bde357
Thanks @thaihuynhxyz! - fix: react extract incorrect resource from encoded pathname - #3126
ccaf8bde357
Thanks @thaihuynhxyz! - fix: react extract incorrect resource from encoded pathname - #3039
54eee2911a2
Thanks @alonp99! - Fixed TypeScript type ofuseParams
hook - #3039
54eee2911a2
Thanks @alonp99! - Fixed TypeScript type ofuseParams
hook - Add missing
BrowserRouterComponent
export to@pankod/refine-react-router-v6
package. - Added ability to manage the initial route of refine by binding
initialRoute
variable toRouterComponent
component.
New routerBindings
export
New routerBindings
contains following properties;
go
: Which returns a function to handle the navigation inreact-router-v6
. It accepts a config object and navigates to the given path. UsesuseNavigate
hook under the hood.back
: Which returns a function to handle the navigation inreact-router-v6
. It navigates back to the previous page. UsesuseNavigate
hook under the hood.parse
: Which returns a function to parse the given path and returns theresource
,id
,action
and additionalparams
. UsesuseParams
anduseLocation
hooks andqs
package under the hood.Link
: A component that acceptsto
prop and renders a link to the given path. UsesLink
component fromreact-router-dom
under the hood.
Complemetary Components
RefineRoutes
- A component that renders the routes for the resources when the actions are defined as components. This can be used to achieve the legacy behavior ofrouterProvider
prop.RefineRoutes
component accepts a render function as a child and passed aJSX.Element
array containingRoute
components for the resource routes. You can wrap it to aRoutes
component and let it handle the route creation process for you. Additionally, If you want to add custom routes, you can place them inside theRoutes
component or you can place an anotherRoutes
component. Both apporaches are now valid and accepted by refine.NavigateToResource
- A component that navigates to the firstlist
action of theresources
array of<Refine>
. Optionally, you can pass aresource
prop to navigate tolist
action of the resource. This can be placed at theindex
route of your app to redirect to the first resource.UnsavedChangesNotifier
- This component handles the prompt when the user tries to leave the page with unsaved changes. It can be placed under theRefine
component.
Exported values from react-router-dom
In earlier versions, we've re-exported the react-router-dom
package. This was a bad practice and we've removed it in this version. If you're using react-router-dom
in your project, you should install it as a dependency and import the values from it.
@refinedev/nextjs-router
Minor Changes
We're releasing a new way to connect your router to refine.
The legacy routerProvider
and its exports are now deprecated but accessible at @refinedev/nextjs-router/legacy-app
and @refinedev/nextjs-router/legacy-pages
.
The new routerBindings
are smaller and more flexible than the previos one.
AuthProvider
is renamed toLegacyAuthProvider
with refine@4. Components and functions are updated to supportLegacyAuthProvider
.parseTableParams
helper is added to let users parse the query params in SSR methods to persistsyncWithLocation
feature in tables.- #3387
a4731bd8fb4
Thanks @vanflux! - Forwarding ref on RefineLink component
Minor Changes
- #3387
a4731bd8fb4
Thanks @vanflux! - Forwarding ref on RefineLink component - #3140
102bfbf3283
Thanks @aliemir! - - Bumped Next.js to 13 - Added support for experimental
appDir
option innext.config.js
to allow for the latest Next.js features.
pages
directory
Current support for pages
directory has not changed and will continue to work as before. It will be supported as long as Next.js
continues to support and prompts it as the stable way of working with Next.js
.
appDir
option
appDir
option is a new experimental feature in Next.js
that introduces a bunch of new features. It is currently in beta and is not stable. It is not recommended to use it in production. But can be used alongside the current pages
directory support.
To use appDir
option, you need to add it to your next.config.js
file.
// next.config.js
module.exports = {
/* ... */
experimental: {
appDir: true,
},
};
Minor Changes
- Added
handleRefineParams
helper function to handle catch-all refine params. - Added ability to parse catch-all refine route in Next.js router. This way, instead of creating multiple pages, users can only create one page at the root
[[...refine]].tsx
and handle all params for the app. - Added ability to manage the initial route of refine by binding
initialRoute
variable toNextRouteComponent
component. - #2486
ee4d0d112a
Thanks @aliemir! - AddedhandleRefineParams
helper function to handle catch-all refine params. - #2486
ee4d0d112a
Thanks @aliemir! - Added ability to parse catch-all refine route in Next.js router. This way, instead of creating multiple pages, users can only create one page at the root[[...refine]].tsx
and handle all params for the app. - #2486
ee4d0d112a
Thanks @aliemir! - Added ability to manage the initial route of refine by bindinginitialRoute
variable toNextRouteComponent
component. - Add
initialData
support toDashboardPage
for@pankod/refine-nextjs-router
.
@refinedev/remix Updates
parseTableParams
helper is added to let users parse the query params in loaders to persist syncWithLocation feature in tables.- #3779
2acb0cd8ad6
Thanks @aliemir! - Updated the brokenPrompt
withuseBlocker
instead of an unsafe workaround. - #3779
2acb0cd8ad6
Thanks @aliemir! - Updated the brokenPrompt
withuseBlocker
instead of an unsafe workaround. - Added ability to manage the initial route of refine by binding
initialRoute
variable toRemixRouteComponent
component. - Add splat route support to remix with
handleRefineParams
helper. - Add ability to manage the initial route of refine by binding
initialRoute
variable toRemixRouteComponent
component. - Add splat route support to remix with
handleRefineParams
helper. - #2486
ee4d0d112a
Thanks @aliemir! - Added ability to manage the initial route of refine by bindinginitialRoute
variable toRemixRouteComponent
component. - #2486
ee4d0d112a
Thanks @aliemir! - Add splat route support to remix withhandleRefineParams
helper.