diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx
index 9c3c6a9d92aa136b37960627141a946f28adb7e5..77b4f737a1ca5f40a55da59c4fc52a120e76140e 100644
--- a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx
+++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsModal.tsx
@@ -1,13 +1,33 @@
+import Image from 'next/image';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { getPublications } from '@/redux/publications/publications.thunks';
 import { useEffect } from 'react';
+import { publicationsListDataSelector } from '@/redux/publications/publications.selectors';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import spinnerIcon from '@/assets/vectors/icons/spinner.svg';
+import { PublicationsTable } from './PublicationsTable/PublicationsTable.component';
 
 export const PublicationsModal = (): JSX.Element => {
   const dispatch = useAppDispatch();
+  const data = useAppSelector(publicationsListDataSelector);
 
   useEffect(() => {
     dispatch(getPublications({}));
   }, [dispatch]);
 
-  return <div className="flex h-full w-full items-center justify-center bg-white">lol</div>;
+  return (
+    <div className="flex w-full flex-1 items-center justify-center overflow-hidden bg-white">
+      {data ? (
+        <PublicationsTable data={data} />
+      ) : (
+        <Image
+          src={spinnerIcon}
+          alt="spinner icon"
+          height={40}
+          width={40}
+          className="animate-spin"
+        />
+      )}
+    </div>
+  );
 };
diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/PublicationsTable.component.tsx b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/PublicationsTable.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..69049b5c37be91bdb4e8e118d62fb3dddebaf91a
--- /dev/null
+++ b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/PublicationsTable.component.tsx
@@ -0,0 +1,133 @@
+import { ONE, ZERO } from '@/constants/common';
+import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import {
+  totalSizeSelector,
+  paginationSelector,
+  isLoadingSelector,
+} from '@/redux/publications/publications.selectors';
+import { getPublications } from '@/redux/publications/publications.thunks';
+import { Button } from '@/shared/Button';
+import { Publication } from '@/types/models';
+import {
+  createColumnHelper,
+  flexRender,
+  getCoreRowModel,
+  useReactTable,
+} from '@tanstack/react-table';
+import { useEffect, useState } from 'react';
+
+const columnHelper = createColumnHelper<Publication>();
+
+const columns = [
+  columnHelper.accessor(row => row.publication.article.pubmedId, { header: 'Pubmed ID' }),
+  columnHelper.accessor(row => row.publication.article.title, { header: 'Title' }),
+  columnHelper.accessor(row => row.publication.article.authors, { header: 'Authors' }),
+  columnHelper.accessor(row => row.publication.article.journal, { header: 'Journal' }),
+  columnHelper.accessor(row => row.publication.article.year, { header: 'Year' }),
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  columnHelper.accessor(row => '{link to element on map}', { header: 'Elements on map' }),
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
+  columnHelper.accessor(row => '{link to submap}', { header: 'Submaps' }),
+];
+
+type PublicationsTableProps = {
+  data: Publication[];
+};
+
+export const PublicationsTable = ({ data }: PublicationsTableProps): JSX.Element => {
+  const dispatch = useAppDispatch();
+  const pagesCount = useAppSelector(totalSizeSelector);
+  const isPublicationsLoading = useAppSelector(isLoadingSelector);
+
+  const reduxPagination = useAppSelector(paginationSelector);
+  const [pagination, setPagination] = useState(reduxPagination);
+  useEffect(() => {
+    dispatch(getPublications({ page: pagination.pageIndex, length: pagination.pageSize }));
+  }, [pagination, dispatch]);
+
+  const table = useReactTable({
+    state: {
+      pagination,
+    },
+    columns,
+    data,
+    getCoreRowModel: getCoreRowModel(),
+    manualPagination: true,
+    pageCount: pagesCount,
+    onPaginationChange: setPagination,
+  });
+
+  return (
+    <div className="flex max-h-full w-full flex-col items-center justify-center bg-white p-6">
+      <div className="overflow-y-auto">
+        <table className="table-auto overflow-auto text-sm">
+          <thead className="sticky top-0 bg-white-pearl">
+            {table.getHeaderGroups().map(headerGroup => (
+              <tr key={headerGroup.id} className="border-y ">
+                {headerGroup.headers.map(header => (
+                  <th key={header.id} className="whitespace-nowrap py-2.5">
+                    {header.isPlaceholder
+                      ? null
+                      : flexRender(header.column.columnDef.header, header.getContext())}
+                  </th>
+                ))}
+              </tr>
+            ))}
+          </thead>
+          <tbody>
+            {data &&
+              table.getRowModel().rows.map(row => (
+                <tr key={row.id} className="even:bg-lotion">
+                  {row.getVisibleCells().map(cell => (
+                    <td key={cell.id} className="p-3">
+                      {flexRender(cell.column.columnDef.cell, cell.getContext())}
+                    </td>
+                  ))}
+                </tr>
+              ))}
+          </tbody>
+        </table>
+      </div>
+      <div className="flex w-full flex-row justify-end border-t">
+        <div className="mt-6 flex flex-row items-center">
+          <Button
+            variantStyles="quiet"
+            className="text-primary-500"
+            onClick={() => table.setPageIndex(ZERO)}
+            disabled={isPublicationsLoading}
+          >
+            First page
+          </Button>
+          <Button
+            variantStyles="secondary"
+            onClick={() => table.previousPage()}
+            disabled={isPublicationsLoading}
+          >
+            Previous page
+          </Button>
+
+          <div className="mx-4 text-sm font-semibold">
+            Page {table.getState().pagination.pageIndex + ONE} out of {table.getPageCount()}
+          </div>
+
+          <Button
+            variantStyles="secondary"
+            onClick={() => table.nextPage()}
+            disabled={isPublicationsLoading}
+          >
+            Next page
+          </Button>
+          <Button
+            variantStyles="quiet"
+            className="text-primary-500"
+            onClick={() => table.setPageIndex(table.getPageCount() - ONE)}
+            disabled={isPublicationsLoading}
+          >
+            Last page
+          </Button>
+        </div>
+      </div>
+    </div>
+  );
+};
diff --git a/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/index.ts b/src/components/FunctionalArea/Modal/PublicationsModal/PublicationsTable/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/redux/apiPath.ts b/src/redux/apiPath.ts
index 95aed0951c702fac177157c88ce24c470776e69d..988efdcb46e83bdaf0754956cc0e7237a2361764 100644
--- a/src/redux/apiPath.ts
+++ b/src/redux/apiPath.ts
@@ -3,7 +3,7 @@ import { PerfectSearchParams } from '@/types/search';
 import { Point } from '@/types/map';
 
 export type GetPublicationsParams = {
-  start?: number;
+  page?: number;
   sortColumn?: string;
   sortOrder?: string;
   level?: number;
@@ -12,7 +12,7 @@ export type GetPublicationsParams = {
 };
 
 const getPublicationsURLSearchParams = ({
-  start,
+  page,
   sortColumn,
   sortOrder,
   level,
@@ -20,7 +20,7 @@ const getPublicationsURLSearchParams = ({
   search,
 }: GetPublicationsParams): URLSearchParams => {
   const params = new URLSearchParams();
-  if (start) params.append('start', start.toString());
+  if (page) params.append('page', page.toString());
   if (sortColumn) params.append('sortColumn', sortColumn);
   if (sortOrder) params.append('sortOrder', sortOrder);
   if (level) params.append('level', level.toString());
@@ -75,7 +75,7 @@ export const apiPath = {
   getMesh: (meshId: string): string => `mesh/${meshId}`,
   getTaxonomy: (taxonomyId: string): string => `taxonomy/${taxonomyId}`,
   getPublications: (params: GetPublicationsParams, modelId = '*'): string =>
-    `/projects/${PROJECT_ID}/models/${modelId}/publications/${getPublicationsURLSearchParams(
+    `/projects/${PROJECT_ID}/models/${modelId}/publications/?${getPublicationsURLSearchParams(
       params,
     )}`,
 };
diff --git a/src/redux/publications/publications.selectors.ts b/src/redux/publications/publications.selectors.ts
index a1fcbb1c3c6f9c90fcb37155eaa75bfbcc957687..81a1b9f34cf8cc93a9b4dd6a8f8d30a09f0e8785 100644
--- a/src/redux/publications/publications.selectors.ts
+++ b/src/redux/publications/publications.selectors.ts
@@ -1,4 +1,5 @@
 import { createSelector } from '@reduxjs/toolkit';
+import { ZERO } from '@/constants/common';
 import { rootSelector } from '../root/root.selectors';
 
 export const publicationsSelector = createSelector(rootSelector, state => state.publications);
@@ -8,9 +9,26 @@ export const publicationsDataSelector = createSelector(
   publications => publications?.data,
 );
 
+export const publicationsListDataSelector = createSelector(
+  publicationsDataSelector,
+  data => data?.data,
+);
+
+/** totalSize is number of pages */
 export const totalSizeSelector = createSelector(publicationsDataSelector, data => data?.totalSize);
 
 export const filteredSizeSelector = createSelector(
   publicationsDataSelector,
   data => data?.filteredSize,
 );
+
+export const currentPageSelector = createSelector(publicationsDataSelector, data => data?.page);
+export const paginationSelector = createSelector(publicationsDataSelector, data => ({
+  pageIndex: data?.page || ZERO,
+  pageSize: 10,
+}));
+
+export const isLoadingSelector = createSelector(
+  publicationsSelector,
+  publications => publications.loading === 'pending',
+);
diff --git a/tailwind.config.ts b/tailwind.config.ts
index a41549602c07c850668d40ae4b784fafdfb237bc..0f75c8f70c01a9fc34cd4d0a7b4e4c4605fb3c36 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -23,6 +23,7 @@ const config: Config = {
         cinnabar: '#ec4d2c',
         'med-sea-green': '#3ab65d',
         cultured: '#f7f7f8',
+        lotion: '#fafafa',
         'white-pearl': '#ffffff',
         divide: '#e1e0e6',
         orange: '#f48c40',