diff --git a/frontend/src/apis/articles.ts b/frontend/src/apis/articles.ts
index f45c3bd81..e3f223ea0 100644
--- a/frontend/src/apis/articles.ts
+++ b/frontend/src/apis/articles.ts
@@ -1,5 +1,10 @@
 import { client } from '.';
-import { ArticleRequest, MetaOgRequest, MetaOgResponse } from '../models/Article';
+import {
+  ArticleBookmarkPutRequest,
+  ArticleRequest,
+  MetaOgRequest,
+  MetaOgResponse,
+} from '../models/Article';
 
 export const requestGetArticles = () => client.get(`/articles`);
 
@@ -8,3 +13,11 @@ export const requestPostArticles = (body: ArticleRequest) => client.post('/artic
 export const requestGetMetaOg = ({ url }: MetaOgRequest) => {
   return client.get<MetaOgResponse>(`/meta-og?url=${url}`);
 };
+
+export const requestPutArticleBookmark = ({ articleId, bookmark }: ArticleBookmarkPutRequest) => {
+  return client.put(`/articles/${articleId}/bookmark`, { checked: bookmark });
+};
+
+export const requestGetFilteredArticle = (course: string, bookmark: boolean) => {
+  return client.get(`/articles?course=${course}&onlyBookmarked=${bookmark}`);
+};
diff --git a/frontend/src/components/Article/Article.style.tsx b/frontend/src/components/Article/Article.style.tsx
index 049d4cba4..13980b9b4 100644
--- a/frontend/src/components/Article/Article.style.tsx
+++ b/frontend/src/components/Article/Article.style.tsx
@@ -1,11 +1,12 @@
 import styled from '@emotion/styled';
+import { css } from '@emotion/react';
 import { COLOR } from '../../constants';
 
 export const Container = styled.li`
   width: 100%;
-  height: 340px;
-  padding: 20px;
-  border-radius: 15px;
+  height: 100%;
+  padding: 10px;
+  border-radius: 8px;
   background-color: #ffffff;
   list-style: none;
 
@@ -20,16 +21,16 @@ export const ThumbnailWrapper = styled.div`
   display: flex;
   justify-content: center;
   align-items: center;
+  aspect-ratio: 16/9;
   width: 100%;
-  height: 154px;
   border-radius: 15px;
-  margin-bottom: 20px;
+  margin-bottom: 10px;
 `;
 
 export const Thumbnail = styled.img`
   width: 100%;
-  height: 154px;
-  border-radius: 15px;
+  height: 100%;
+  border-radius: 8px;
   object-fit: cover;
 `;
 
@@ -41,34 +42,57 @@ export const ArticleInfoContainer = styled.div`
   padding: 10px;
 `;
 
-export const UserName = styled.p`
-  width: 250px;
-  margin: 0;
-  color: ${COLOR.DARK_GRAY_400};
-  font-size: 14px;
+export const ArticleInfoWrapper = styled.div`
+  display: flex;
+  width: 100%;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
   word-break: break-all;
+  font-size: 14px;
+`;
+
+export const UserName = styled.p`
+  margin: 0;
+  color: ${COLOR.DARK_GRAY_400};
 `;
 
 export const Title = styled.p`
-  width: 250px;
+  width: 100%;
+  height: 50px;
   margin: 0;
   color: ${COLOR.BLACK_900};
   font-size: 16px;
   font-weight: 700;
-  overflow: hidden;
   text-overflow: ellipsis;
-  white-space: nowrap;
-  word-break: break-all;
+  overflow: hidden;
+  word-break: break-word;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+`;
+
+export const BookmarkWrapper = styled.div`
+  width: 100%;
+  display: flex;
+  justify-content: flex-end;
+`;
+
+export const ArticleBookmarkButtonStyle = css`
+  width: initial;
+  background-color: transparent;
+  text-align: right;
+
+  & > img {
+    width: 2.3rem;
+    height: 2.3rem;
+  }
 `;
 
 export const CreatedAt = styled.span`
   width: 100%;
-  margin-top: 16px;
   color: ${COLOR.DARK_GRAY_400};
   text-align: right;
-  font-size: 16px;
+  font-size: 12px;
   font-weight: 700;
 `;
diff --git a/frontend/src/components/Article/Article.tsx b/frontend/src/components/Article/Article.tsx
index c610c38af..0d55d5f71 100644
--- a/frontend/src/components/Article/Article.tsx
+++ b/frontend/src/components/Article/Article.tsx
@@ -1,7 +1,26 @@
 import * as Styled from './Article.style';
 import type { ArticleType } from '../../models/Article';
+import Scrap from '../Reaction/Scrap';
+import { useRef, useState } from 'react';
+import { usePutArticleBookmarkMutation } from '../../hooks/queries/article';
+import debounce from '../../utils/debounce';
+
+const Article = ({ id, title, userName, url, createdAt, imageUrl, isBookMarked }: ArticleType) => {
+  const bookmarkRef = useRef(false);
+  const [bookmark, setBookmark] = useState(isBookMarked);
+  const { mutate: putBookmark } = usePutArticleBookmarkMutation();
+
+  const toggleBookmark: React.MouseEventHandler<HTMLButtonElement> = (e) => {
+    e.preventDefault();
+
+    bookmarkRef.current = !bookmarkRef.current;
+    setBookmark((prev) => !prev);
+
+    debounce(() => {
+      putBookmark({ articleId: id, bookmark: bookmarkRef.current });
+    }, 300);
+  };
 
-const Article = ({ title, userName, url, createdAt, imageUrl }: ArticleType) => {
   return (
     <Styled.Container>
       <Styled.Anchor href={url} target="_blank" rel="noopener noreferrer">
@@ -9,9 +28,18 @@ const Article = ({ title, userName, url, createdAt, imageUrl }: ArticleType) =>
           <Styled.Thumbnail src={imageUrl} />
         </Styled.ThumbnailWrapper>
         <Styled.ArticleInfoContainer>
-          <Styled.UserName>{userName}</Styled.UserName>
+          <Styled.ArticleInfoWrapper>
+            <Styled.UserName>{userName}</Styled.UserName>
+            <Styled.CreatedAt>{createdAt.split(' ')[0]}</Styled.CreatedAt>
+          </Styled.ArticleInfoWrapper>
           <Styled.Title>{title}</Styled.Title>
-          <Styled.CreatedAt>{createdAt}</Styled.CreatedAt>
+          <Styled.BookmarkWrapper>
+            <Scrap
+              scrap={bookmark}
+              onClick={toggleBookmark}
+              cssProps={Styled.ArticleBookmarkButtonStyle}
+            />
+          </Styled.BookmarkWrapper>
         </Styled.ArticleInfoContainer>
       </Styled.Anchor>
     </Styled.Container>
diff --git a/frontend/src/components/Article/ArticleBookmarkFIlter.tsx b/frontend/src/components/Article/ArticleBookmarkFIlter.tsx
new file mode 100644
index 000000000..9fb48f7d9
--- /dev/null
+++ b/frontend/src/components/Article/ArticleBookmarkFIlter.tsx
@@ -0,0 +1,28 @@
+import styled from '@emotion/styled';
+
+interface ArticleBookmarkFilterProps {
+  checked: boolean;
+  handleCheckBookmark: React.ChangeEventHandler<HTMLInputElement>;
+}
+
+const ArticleBookmarkFilter = ({ checked, handleCheckBookmark }: ArticleBookmarkFilterProps) => {
+  return (
+    <ArticleBookmarkFilterContainer>
+      <label>
+        <input type="checkbox" checked={checked} onChange={handleCheckBookmark} />
+        북마크한 아티클
+      </label>
+    </ArticleBookmarkFilterContainer>
+  );
+};
+
+export default ArticleBookmarkFilter;
+
+const ArticleBookmarkFilterContainer = styled.div`
+  display: flex;
+  align-items: center;
+  margin-left: 10px;
+  width: 150px;
+  height: 100%;
+  font-size: 1.5rem;
+`;
diff --git a/frontend/src/components/Article/ArticleList.style.tsx b/frontend/src/components/Article/ArticleList.style.tsx
index b7d21cadd..e941cfc56 100644
--- a/frontend/src/components/Article/ArticleList.style.tsx
+++ b/frontend/src/components/Article/ArticleList.style.tsx
@@ -3,19 +3,19 @@ import MEDIA_QUERY from '../../constants/mediaQuery';
 
 export const Container = styled.ul`
   display: grid;
-  grid-template-columns: repeat(3, 1fr);
+  grid-template-columns: repeat(4, 1fr);
   grid-auto-rows: 1fr;
-  gap: 30px 64px;
+  gap: 10px;
 
-  ${MEDIA_QUERY.xl} {
-    gap: 30px 40px;
+  ${MEDIA_QUERY.lg} {
+    grid-template-columns: repeat(3, 1fr);
   }
 
-  ${MEDIA_QUERY.lg} {
+  ${MEDIA_QUERY.md} {
     grid-template-columns: repeat(2, 1fr);
   }
 
-  ${MEDIA_QUERY.md} {
+  ${MEDIA_QUERY.sm} {
     grid-template-columns: repeat(1, 1fr);
   }
 `;
diff --git a/frontend/src/components/Article/ArticleList.tsx b/frontend/src/components/Article/ArticleList.tsx
index 5aebbfe49..59fd386ce 100644
--- a/frontend/src/components/Article/ArticleList.tsx
+++ b/frontend/src/components/Article/ArticleList.tsx
@@ -1,13 +1,12 @@
 import * as Styled from './ArticleList.style';
 import Article from './Article';
-import { useGetRequestArticleQuery } from '../../hooks/queries/article';
+import { ArticleType } from '../../models/Article';
 
-const ArticleList = () => {
-  const { data: articles, isLoading, isError } = useGetRequestArticleQuery();
-
-  if (isLoading) return <div>loading...</div>;
-  if (isError) return <div>error...</div>;
+interface ArticleListProps {
+  articles: ArticleType[];
+}
 
+const ArticleList = ({ articles }: ArticleListProps) => {
   return (
     <Styled.Container>
       {articles?.map((article) => (
diff --git a/frontend/src/components/Controls/SelectBox.tsx b/frontend/src/components/Controls/SelectBox.tsx
index 7a0fa1edb..168875962 100644
--- a/frontend/src/components/Controls/SelectBox.tsx
+++ b/frontend/src/components/Controls/SelectBox.tsx
@@ -34,6 +34,25 @@ interface SelectOption {
   label: string;
 }
 
+/**
+  FIXME: value props type SelectOption['value'] 로 변경되어야 함.
+  아래 예시처럼 type을 좁힐 수 없는 문제가 있음.
+
+  const CATEGORY_OPTIONS = [
+    { value: '', label: '전체보기' },
+    { value: 'frontend', label: '프론트엔드' },
+    { value: 'backend', label: '백엔드' },
+    { value: 'android', label: '안드로이드' },
+  ];
+
+  type CategoryOptions = typeof CATEGORY_OPTIONS[number]; 
+
+  ->type CategoryOptions = {
+      value: string;
+      label: string;
+    }
+  위 처럼 value type을 좁힐 수 없음.
+ */
 interface SelectBoxProps {
   isMulti?: boolean;
   options: SelectOption[];
@@ -46,6 +65,7 @@ interface SelectBoxProps {
 }
 
 const SelectBox: React.VFC<SelectBoxProps> = ({
+  isClearable = true,
   isMulti = false,
   options,
   placeholder,
@@ -75,7 +95,7 @@ const SelectBox: React.VFC<SelectBoxProps> = ({
     `}
   >
     <Select
-      isClearable={true}
+      isClearable={isClearable}
       isMulti={isMulti}
       options={options}
       placeholder={placeholder}
@@ -83,7 +103,6 @@ const SelectBox: React.VFC<SelectBoxProps> = ({
       styles={selectStyles}
       defaultValue={defaultOption}
       value={value}
-      // theme={(theme) => ({ ...theme, colors: { ...theme.colors, primary: 'transparent' } })}
     />
   </div>
 );
diff --git a/frontend/src/components/Reaction/Scrap.styles.ts b/frontend/src/components/Reaction/Scrap.styles.ts
index 2335d252a..976533905 100644
--- a/frontend/src/components/Reaction/Scrap.styles.ts
+++ b/frontend/src/components/Reaction/Scrap.styles.ts
@@ -1,7 +1,7 @@
 import { css } from '@emotion/react';
 import { COLOR } from '../../enumerations/color';
 
-export const ScrapButtonStyle = css`
+export const DefaultScrapButtonStyle = css`
   flex-direction: column;
   padding: 0;
   width: fit-content;
diff --git a/frontend/src/components/Reaction/Scrap.tsx b/frontend/src/components/Reaction/Scrap.tsx
index 08bfad860..9a30aa9ec 100644
--- a/frontend/src/components/Reaction/Scrap.tsx
+++ b/frontend/src/components/Reaction/Scrap.tsx
@@ -3,14 +3,16 @@ import { Button, BUTTON_SIZE } from '..';
 
 import scrappedIcon from '../../assets/images/scrap_filled.svg';
 import unScrapIcon from '../../assets/images/scrap.svg';
-import { ScrapButtonStyle } from './Scrap.styles';
+import { DefaultScrapButtonStyle } from './Scrap.styles';
+import { SerializedStyles } from '@emotion/react';
 
 interface Props {
   scrap: boolean;
   onClick: MouseEventHandler<HTMLButtonElement>;
+  cssProps?: SerializedStyles;
 }
 
-const Scrap = ({ scrap, onClick }: Props) => {
+const Scrap = ({ scrap, onClick, cssProps }: Props) => {
   const scrapIcon = scrap ? scrappedIcon : unScrapIcon;
   const scrapIconAlt = scrap ? '스크랩 취소' : '스크랩';
 
@@ -20,7 +22,7 @@ const Scrap = ({ scrap, onClick }: Props) => {
       size={BUTTON_SIZE.X_SMALL}
       icon={scrapIcon}
       alt={scrapIconAlt}
-      cssProps={ScrapButtonStyle}
+      cssProps={cssProps ?? DefaultScrapButtonStyle}
       onClick={onClick}
     />
   );
diff --git a/frontend/src/hooks/queries/article.ts b/frontend/src/hooks/queries/article.ts
index 4e6780cbf..f62cd49f8 100644
--- a/frontend/src/hooks/queries/article.ts
+++ b/frontend/src/hooks/queries/article.ts
@@ -1,17 +1,20 @@
 import { useMutation, useQuery, useQueryClient } from 'react-query';
-import { UserContext } from '../../contexts/UserProvider';
-import { requestGetArticles, requestPostArticles } from '../../apis/articles';
-import { ArticleType } from '../../models/Article';
+import {
+  requestGetFilteredArticle,
+  requestPostArticles,
+  requestPutArticleBookmark,
+} from '../../apis/articles';
+import { ArticleType, CourseFilter } from '../../models/Article';
 import { ERROR_MESSAGE } from '../../constants';
 import { SUCCESS_MESSAGE } from '../../constants/message';
 
 const QUERY_KEY = {
-  articles: 'articles',
+  filteredArticles: 'filteredArticles',
 };
 
-export const useGetRequestArticleQuery = () => {
-  return useQuery<ArticleType[]>([QUERY_KEY.articles], async () => {
-    const response = await requestGetArticles();
+export const useGetFilteredArticleQuery = (course: string, bookmark: boolean) => {
+  return useQuery<ArticleType[]>([QUERY_KEY.filteredArticles], async () => {
+    const response = await requestGetFilteredArticle(course, bookmark);
 
     return response.data;
   });
@@ -22,7 +25,7 @@ export const usePostArticlesMutation = () => {
 
   return useMutation(requestPostArticles, {
     onSuccess: () => {
-      queryClient.invalidateQueries([QUERY_KEY.articles]);
+      queryClient.invalidateQueries([QUERY_KEY.filteredArticles]);
       alert(SUCCESS_MESSAGE.CREATE_ARTICLE);
     },
     onError: () => {
@@ -30,3 +33,10 @@ export const usePostArticlesMutation = () => {
     },
   });
 };
+
+export const usePutArticleBookmarkMutation = () => {
+  return useMutation(requestPutArticleBookmark, {
+    onSuccess: () => {},
+    onError: () => {},
+  });
+};
diff --git a/frontend/src/mocks/db/articles-android.json b/frontend/src/mocks/db/articles-android.json
new file mode 100644
index 000000000..865954a4c
--- /dev/null
+++ b/frontend/src/mocks/db/articles-android.json
@@ -0,0 +1,29 @@
+[
+  {
+    "id": 7,
+    "userName": "도밥",
+    "title": "직렬화, 역직렬화는 무엇일까?",
+    "url": "https://think0wise.tistory.com/107",
+    "createdAt": "2023-07-08 16:48",
+    "isBookMarked": false,
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 8,
+    "userName": "도밥",
+    "title": "직렬화, 역직렬화는 무엇일까?",
+    "url": "https://think0wise.tistory.com/107",
+    "createdAt": "2023-07-08 16:48",
+    "isBookMarked": true,
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 9,
+    "userName": "도밥",
+    "title": "직렬화, 역직렬화는 무엇일까?",
+    "url": "https://think0wise.tistory.com/107",
+    "createdAt": "2023-07-08 16:48",
+    "isBookMarked": false,
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  }
+]
diff --git a/frontend/src/mocks/db/articles-backend.json b/frontend/src/mocks/db/articles-backend.json
new file mode 100644
index 000000000..f3fdaae4c
--- /dev/null
+++ b/frontend/src/mocks/db/articles-backend.json
@@ -0,0 +1,29 @@
+[
+  {
+    "id": 4,
+    "userName": "패트릭",
+    "title": "CORS",
+    "isBookMarked": false,
+    "url": "https://pgccoding.tistory.com/66",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 5,
+    "userName": "패트릭",
+    "title": "CORS",
+    "isBookMarked": true,
+    "url": "https://pgccoding.tistory.com/66",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 6,
+    "userName": "패트릭",
+    "title": "CORS",
+    "isBookMarked": true,
+    "url": "https://pgccoding.tistory.com/66",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  }
+]
diff --git a/frontend/src/mocks/db/articles-frontend.json b/frontend/src/mocks/db/articles-frontend.json
new file mode 100644
index 000000000..d7da0c5e8
--- /dev/null
+++ b/frontend/src/mocks/db/articles-frontend.json
@@ -0,0 +1,29 @@
+[
+  {
+    "id": 1,
+    "userName": "해온",
+    "title": "Axios",
+    "isBookMarked": true,
+    "url": "https://hae-on.tistory.com/104",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 2,
+    "userName": "해온",
+    "title": "Axios",
+    "isBookMarked": true,
+    "url": "https://hae-on.tistory.com/104",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 3,
+    "userName": "해온",
+    "title": "Axios",
+    "isBookMarked": true,
+    "url": "https://hae-on.tistory.com/104",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  }
+]
diff --git a/frontend/src/mocks/db/articles.json b/frontend/src/mocks/db/articles.json
index 9105fbb0a..35b46c204 100644
--- a/frontend/src/mocks/db/articles.json
+++ b/frontend/src/mocks/db/articles.json
@@ -3,16 +3,81 @@
     "id": 1,
     "userName": "해온",
     "title": "Axios",
+    "isBookMarked": true,
     "url": "https://hae-on.tistory.com/104",
     "createdAt": "2023-07-24 18:18",
     "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
   },
   {
     "id": 2,
+    "userName": "해온",
+    "title": "Axios",
+    "isBookMarked": true,
+    "url": "https://hae-on.tistory.com/104",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 3,
+    "userName": "해온",
+    "title": "Axios",
+    "isBookMarked": true,
+    "url": "https://hae-on.tistory.com/104",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 4,
     "userName": "패트릭",
     "title": "CORS",
+    "isBookMarked": false,
     "url": "https://pgccoding.tistory.com/66",
     "createdAt": "2023-07-24 18:18",
     "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 5,
+    "userName": "패트릭",
+    "title": "CORS",
+    "isBookMarked": true,
+    "url": "https://pgccoding.tistory.com/66",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 6,
+    "userName": "패트릭",
+    "title": "CORS",
+    "isBookMarked": true,
+    "url": "https://pgccoding.tistory.com/66",
+    "createdAt": "2023-07-24 18:18",
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 7,
+    "userName": "도밥",
+    "title": "직렬화, 역직렬화는 무엇일까?",
+    "url": "https://think0wise.tistory.com/107",
+    "createdAt": "2023-07-08 16:48",
+    "isBookMarked": false,
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 8,
+    "userName": "도밥",
+    "title": "직렬화, 역직렬화는 무엇일까?",
+    "url": "https://think0wise.tistory.com/107",
+    "createdAt": "2023-07-08 16:48",
+    "isBookMarked": true,
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
+  },
+  {
+    "id": 9,
+    "userName": "도밥",
+    "title": "직렬화, 역직렬화는 무엇일까?",
+    "url": "https://think0wise.tistory.com/107",
+    "createdAt": "2023-07-08 16:48",
+    "isBookMarked": false,
+    "imageUrl": "https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60"
   }
 ]
diff --git a/frontend/src/mocks/handlers/articles.ts b/frontend/src/mocks/handlers/articles.ts
index c9b74676e..6571fa4fa 100644
--- a/frontend/src/mocks/handlers/articles.ts
+++ b/frontend/src/mocks/handlers/articles.ts
@@ -1,15 +1,18 @@
 import { rest } from 'msw';
 import { BASE_URL } from '../../configs/environment';
 import articles from '../db/articles.json';
+import articlesFrontend from '../db/articles-frontend.json';
+import articlesBackend from '../db/articles-backend.json';
+import articlesAndroid from '../db/articles-android.json';
 import metaOg from '../db/metaog.json';
 import { ArticleType } from '../../models/Article';
 
 const articleUrl = 'https://think0wise.tistory.com/107';
 
 export const articlesHandler = [
-  rest.get(`${BASE_URL}/articles`, (req, res, ctx) => {
-    return res(ctx.status(200), ctx.json(articles));
-  }),
+  // rest.get(`${BASE_URL}/articles`, (req, res, ctx) => {
+  //   return res(ctx.status(200), ctx.json(articles));
+  // }),
 
   rest.get(`${BASE_URL}/meta-og?url=${articleUrl}`, async (req, res, ctx) => {
     const data = metaOg;
@@ -24,6 +27,7 @@ export const articlesHandler = [
       title: '직렬화, 역직렬화는 무엇일까?',
       url: 'https://think0wise.tistory.com/107',
       createdAt: '2023-07-08 16:48',
+      isBookMarked: false,
       imageUrl:
         'https://plus.unsplash.com/premium_photo-1682088845396-1b310a002302?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MXx8JUVDJTk1JTg0JUVEJThCJUIwJUVEJTgxJUI0fGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60',
     };
@@ -31,4 +35,30 @@ export const articlesHandler = [
     articles.push(newArticle);
     return res(ctx.status(200), ctx.json(newArticle));
   }),
+
+  rest.put(`${BASE_URL}/articles/:articleId/bookmark`, (req, res, ctx) => {
+    return res(ctx.status(200));
+  }),
+
+  rest.get(`${BASE_URL}/articles`, (req, res, ctx) => {
+    const course = req.url.searchParams.get('course') ?? 'all';
+    const onlyBookmarked = req.url.searchParams.get('onlyBookmarked') as string;
+
+    const filteredCourse = (course: string) => {
+      if (course === 'all') return articles;
+      if (course === 'frontend') return articlesFrontend;
+      if (course === 'backend') return articlesBackend;
+      if (course === 'android') return articlesAndroid;
+    };
+
+    if (onlyBookmarked === 'false') {
+      return res(ctx.status(200), ctx.json(filteredCourse(course)));
+    }
+
+    const filteredArticle = filteredCourse(course)?.filter((article) => {
+      return onlyBookmarked === String(article.isBookMarked) ? true : false;
+    });
+
+    return res(ctx.status(200), ctx.json(filteredArticle));
+  }),
 ];
diff --git a/frontend/src/models/Article.ts b/frontend/src/models/Article.ts
index 742bcfd9b..dc7540160 100644
--- a/frontend/src/models/Article.ts
+++ b/frontend/src/models/Article.ts
@@ -8,6 +8,7 @@ export interface ArticleType {
   id: number;
   userName: string;
   title: string;
+  isBookMarked: boolean;
   url: string;
   createdAt: string;
   imageUrl: string;
@@ -21,3 +22,12 @@ export interface MetaOgResponse {
   imageUrl: string;
   title: string;
 }
+
+export interface ArticleBookmarkPutRequest {
+  articleId: number;
+  bookmark: boolean;
+}
+
+export type Course = '프론트엔드' | '백엔드' | '안드로이드';
+
+export type CourseFilter = Course | '전체보기';
diff --git a/frontend/src/pages/ArticleListPage/index.tsx b/frontend/src/pages/ArticleListPage/index.tsx
index 4c4f8cc2c..9f6882c0e 100644
--- a/frontend/src/pages/ArticleListPage/index.tsx
+++ b/frontend/src/pages/ArticleListPage/index.tsx
@@ -4,28 +4,82 @@ import ArticleList from '../../components/Article/ArticleList';
 import { Button } from '../../components';
 import PencilIcon from '../../assets/images/pencil_icon.svg';
 import { useHistory } from 'react-router-dom';
-import { PATH } from '../../constants';
+import { COLOR, PATH } from '../../constants';
 import styled from '@emotion/styled';
 import { MainContentStyle } from '../../PageRouter';
+import SelectBox from '../../components/Controls/SelectBox';
+import { useContext, useEffect, useState } from 'react';
+import { css } from '@emotion/react';
+import ArticleBookmarkFilter from '../../components/Article/ArticleBookmarkFIlter';
+import { useGetFilteredArticleQuery } from '../../hooks/queries/article';
+import { UserContext } from '../../contexts/UserProvider';
+
+const CATEGORY_OPTIONS = [
+  { value: 'all', label: '전체보기' },
+  { value: 'frontend', label: '프론트엔드' },
+  { value: 'backend', label: '백엔드' },
+  { value: 'android', label: '안드로이드' },
+];
+
+type CategoryOptions = typeof CATEGORY_OPTIONS[number];
 
 const ArticleListPage = () => {
   const history = useHistory();
   const goNewArticlePage = () => history.push(PATH.NEW_ARTICLE);
+  const [selectedCourse, setSelectedCourse] = useState<CategoryOptions>(CATEGORY_OPTIONS[0]);
+  const [checked, setChecked] = useState(false);
+
+  const { user } = useContext(UserContext);
+  const { isLoggedIn } = user;
+
+  const { data: filteredArticles = [], refetch: getFilteredArticles } = useGetFilteredArticleQuery(
+    selectedCourse.value,
+    checked
+  );
+
+  const changeFilterOption: (option: { value: string; label: string }) => void = (option) => {
+    setSelectedCourse(option);
+  };
+
+  const handleCheckBookmark: React.ChangeEventHandler<HTMLInputElement> = (e) => {
+    setChecked(e.currentTarget.checked);
+  };
+
+  useEffect(() => {
+    getFilteredArticles();
+  }, [checked, selectedCourse]);
 
   return (
     <div css={[MainContentStyle]}>
       <Container>
-        <Button
-          type="button"
-          size="SMALL"
-          icon={PencilIcon}
-          alt="새 아티클 쓰기 아이콘"
-          onClick={goNewArticlePage}
-        >
-          글쓰기
-        </Button>
+        <FilteringWrapper>
+          <SelectBoxWrapper>
+            <SelectBox
+              isClearable={false}
+              value={selectedCourse}
+              defaultOption={selectedCourse}
+              options={CATEGORY_OPTIONS}
+              onChange={changeFilterOption}
+            />
+          </SelectBoxWrapper>
+          {isLoggedIn && (
+            <ArticleBookmarkFilter checked={checked} handleCheckBookmark={handleCheckBookmark} />
+          )}
+        </FilteringWrapper>
+        {isLoggedIn && (
+          <Button
+            type="button"
+            size="X_SMALL"
+            icon={PencilIcon}
+            alt="새 아티클 쓰기 아이콘"
+            onClick={goNewArticlePage}
+            cssProps={WriteButtonStyle}
+          >
+            글쓰기
+          </Button>
+        )}
       </Container>
-      <ArticleList />
+      <ArticleList articles={filteredArticles} />
     </div>
   );
 };
@@ -34,7 +88,31 @@ export default ArticleListPage;
 
 export const Container = styled.div`
   display: flex;
-  flex-direction: column;
-  align-items: flex-end;
+  flex-direction: row;
+  justify-content: space-between;
   margin-bottom: 20px;
+  gap: 15px;
+`;
+
+const FilteringWrapper = styled.div`
+  display: flex;
+`;
+
+const SelectBoxWrapper = styled.div`
+  width: 150px;
+`;
+
+export const WriteButtonStyle = css`
+  width: 100px;
+  height: 42px;
+  padding: 0.2rem 0.8rem;
+
+  border-radius: 0.6rem;
+  font-size: 1.6rem;
+
+  color: ${COLOR.WHITE};
+
+  :hover {
+    background-color: ${COLOR.DARK_BLUE_600};
+  }
 `;