diff --git a/app/assets/javascripts/pages/projects/ci/lints/ci_lint_editor.js b/app/assets/javascripts/pages/projects/ci/lints/ci_lint_editor.js
deleted file mode 100644
index df635522e94ce6d786ae76fb341d461528f34a22..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/pages/projects/ci/lints/ci_lint_editor.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import EditorLite from '~/editor/editor_lite';
-
-export default class CILintEditor {
-  constructor() {
-    this.clearYml = document.querySelector('.clear-yml');
-    this.clearYml.addEventListener('click', this.clear.bind(this));
-
-    return this.initEditorLite();
-  }
-
-  clear() {
-    this.editor.setValue('');
-  }
-
-  initEditorLite() {
-    const editorEl = document.getElementById('editor');
-    const fileContentEl = document.getElementById('content');
-    const form = document.querySelector('.js-ci-lint-form');
-
-    const rootEditor = new EditorLite();
-
-    this.editor = rootEditor.createInstance({
-      el: editorEl,
-      blobPath: '.gitlab-ci.yml',
-      blobContent: editorEl.innerText,
-    });
-
-    form.addEventListener('submit', () => {
-      fileContentEl.value = this.editor.getValue();
-    });
-  }
-}
diff --git a/app/assets/javascripts/pages/projects/ci/lints/new/index.js b/app/assets/javascripts/pages/projects/ci/lints/new/index.js
deleted file mode 100644
index 5a0689b15f24c058594bc547d5f70cbd064c26b9..0000000000000000000000000000000000000000
--- a/app/assets/javascripts/pages/projects/ci/lints/new/index.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import createFlash from '~/flash';
-import { __ } from '~/locale';
-
-const ERROR = __('An error occurred while rendering the linter');
-
-document.addEventListener('DOMContentLoaded', () => {
-  if (gon?.features?.ciLintVue) {
-    import(/* webpackChunkName: 'ciLintIndex' */ '~/ci_lint/index')
-      .then(module => module.default())
-      .catch(() => createFlash({ message: ERROR }));
-  } else {
-    import(/* webpackChunkName: 'ciLintEditor' */ '../ci_lint_editor')
-      // eslint-disable-next-line new-cap
-      .then(module => new module.default())
-      .catch(() => createFlash({ message: ERROR }));
-  }
-});
diff --git a/app/assets/javascripts/pages/projects/ci/lints/show/index.js b/app/assets/javascripts/pages/projects/ci/lints/show/index.js
index 5a0689b15f24c058594bc547d5f70cbd064c26b9..6e1cdf557b593a9148d150d7ac5d4bb608c4c7f1 100644
--- a/app/assets/javascripts/pages/projects/ci/lints/show/index.js
+++ b/app/assets/javascripts/pages/projects/ci/lints/show/index.js
@@ -1,17 +1,3 @@
-import createFlash from '~/flash';
-import { __ } from '~/locale';
+import initCiLint from '~/ci_lint';
 
-const ERROR = __('An error occurred while rendering the linter');
-
-document.addEventListener('DOMContentLoaded', () => {
-  if (gon?.features?.ciLintVue) {
-    import(/* webpackChunkName: 'ciLintIndex' */ '~/ci_lint/index')
-      .then(module => module.default())
-      .catch(() => createFlash({ message: ERROR }));
-  } else {
-    import(/* webpackChunkName: 'ciLintEditor' */ '../ci_lint_editor')
-      // eslint-disable-next-line new-cap
-      .then(module => new module.default())
-      .catch(() => createFlash({ message: ERROR }));
-  }
-});
+initCiLint();
diff --git a/app/controllers/projects/ci/lints_controller.rb b/app/controllers/projects/ci/lints_controller.rb
index 26797a4613c5084653884d9460a95d1d821e4858..9dc3194df8510cfa347891c5298dd4ed82618e81 100644
--- a/app/controllers/projects/ci/lints_controller.rb
+++ b/app/controllers/projects/ci/lints_controller.rb
@@ -2,28 +2,22 @@
 
 class Projects::Ci::LintsController < Projects::ApplicationController
   before_action :authorize_create_pipeline!
-  before_action do
-    push_frontend_feature_flag(:ci_lint_vue, project, default_enabled: true)
-  end
 
   feature_category :pipeline_authoring
 
+  respond_to :json, only: [:create]
+
   def show
   end
 
   def create
-    @content = params[:content]
-    @dry_run = params[:dry_run]
+    content = params[:content]
+    dry_run = params[:dry_run]
 
-    @result = Gitlab::Ci::Lint
+    result = Gitlab::Ci::Lint
       .new(project: @project, current_user: current_user)
-      .validate(@content, dry_run: @dry_run)
+      .validate(content, dry_run: dry_run)
 
-    respond_to do |format|
-      format.html { render :show }
-      format.json do
-        render json: ::Ci::Lint::ResultSerializer.new.represent(@result)
-      end
-    end
+    render json: ::Ci::Lint::ResultSerializer.new.represent(result)
   end
 end
diff --git a/app/views/projects/ci/lints/_create.html.haml b/app/views/projects/ci/lints/_create.html.haml
deleted file mode 100644
index 8afa5c220ba1ad3c6a1f150484a3ed789d8d2041..0000000000000000000000000000000000000000
--- a/app/views/projects/ci/lints/_create.html.haml
+++ /dev/null
@@ -1,51 +0,0 @@
-- if @result.valid?
-  .bs-callout.bs-callout-success
-    %p
-      %b= _("Status:")
-      = _("syntax is correct")
-
-  = render "projects/ci/lints/lint_warnings", warnings: @result.warnings
-
-  .table-holder
-    %table.table.table-bordered
-      %thead
-        %tr
-          %th= _("Parameter")
-          %th= _("Value")
-      %tbody
-        - @result.jobs.each do |job|
-          %tr
-            %td #{job[:stage].capitalize} Job - #{job[:name]}
-            %td
-              %pre= job[:before_script].to_a.join('<br />')
-              %pre= job[:script].to_a.join('<br />')
-              %pre= job[:after_script].to_a.join('<br />')
-              %br
-              %b= _("Tag list:")
-              = job[:tag_list].to_a.join(", ")
-              - unless @dry_run
-                %br
-                %b= _("Only policy:")
-                = job[:only].to_a.join(", ")
-                %br
-                %b= _("Except policy:")
-                = job[:except].to_a.join(", ")
-              %br
-              %b= _("Environment:")
-              = job[:environment]
-              %br
-              %b= _("When:")
-              = job[:when]
-              - if job[:allow_failure]
-                %b= _("Allowed to fail")
-
-- else
-  .bs-callout.bs-callout-danger
-    %p
-      %b= _("Status:")
-      = _("syntax is incorrect")
-  %pre
-    - @result.errors.each do |message|
-      %p= message
-
-  = render "projects/ci/lints/lint_warnings", warnings: @result.warnings
diff --git a/app/views/projects/ci/lints/_lint_warnings.html.haml b/app/views/projects/ci/lints/_lint_warnings.html.haml
deleted file mode 100644
index 90db65e6c27e9d782d33115f0b2f3bc881bd55e1..0000000000000000000000000000000000000000
--- a/app/views/projects/ci/lints/_lint_warnings.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- if warnings
-  - total_warnings = warnings.length
-  - message = warning_header(total_warnings)
-
-  - if warnings.any?
-    .bs-callout.bs-callout-warning
-      %details
-        %summary.gl-mb-2= message
-        - warnings.each do |warning|
-          = markdown(warning)
diff --git a/app/views/projects/ci/lints/show.html.haml b/app/views/projects/ci/lints/show.html.haml
index 9eaaba0e909d74ee0af55907fc33b4a7ec849b8e..1b1bef1f85ce19914b8d5956d98b4b936f7e89dd 100644
--- a/app/views/projects/ci/lints/show.html.haml
+++ b/app/views/projects/ci/lints/show.html.haml
@@ -3,32 +3,4 @@
 
 %h2.pt-3.pb-3= _("Validate your GitLab CI configuration")
 
-- if Feature.enabled?(:ci_lint_vue, @project, default_enabled: true)
-  #js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') } }
-
-- else
-  .project-ci-linter
-    = form_tag project_ci_lint_path(@project), method: :post, class: 'js-ci-lint-form' do
-      .row
-        .col-sm-12
-          .file-holder
-            .js-file-title.file-title.clearfix
-              = _("Contents of .gitlab-ci.yml")
-            .file-editor.code
-              .js-edit-mode-pane.qa-editor#editor{ data: { 'editor-loading': true } }<
-                %pre.editor-loading-content= params[:content]
-          = text_area_tag(:content, @content, class: 'hidden form-control span1', rows: 7, require: true)
-        .col-sm-12
-          .float-left.gl-mt-3
-            = submit_tag(_('Validate'), class: 'gl-button btn btn-success submit-yml')
-            - if Gitlab::Ci::Features.lint_creates_pipeline_with_dry_run?(@project)
-              = check_box_tag(:dry_run, 'true', params[:dry_run])
-              = label_tag(:dry_run, _('Simulate a pipeline created for the default branch'))
-              = link_to sprite_icon('question-o'), help_page_path('ci/lint', anchor: 'pipeline-simulation'), target: '_blank', rel: 'noopener noreferrer'
-          .float-right.prepend-top-10
-            = button_tag(_('Clear'), type: 'button', class: 'gl-button btn btn-default clear-yml')
-
-    .row.prepend-top-20
-      .col-sm-12
-        .results.project-ci-template
-          = render partial: 'create' if defined?(@result)
+#js-ci-lint{ data: { endpoint: project_ci_lint_path(@project), help_page_path: help_page_path('ci/lint', anchor: 'pipeline-simulation') } }
diff --git a/config/feature_flags/development/ci_lint_vue.yml b/config/feature_flags/development/ci_lint_vue.yml
deleted file mode 100644
index 0997da761c0214c4e2e42a0ac8c8f6c03a04e85c..0000000000000000000000000000000000000000
--- a/config/feature_flags/development/ci_lint_vue.yml
+++ /dev/null
@@ -1,7 +0,0 @@
----
-name: ci_lint_vue
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42401
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/249661
-group: group::continuous integration
-type: development
-default_enabled: true
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 2a3d8c23e89d735de5518dd2ea63faf84fae7e23..95c8e8ab65885894aa23d4953dd77ce434d4cb56 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3154,9 +3154,6 @@ msgstr ""
 msgid "An error occurred while rendering the editor"
 msgstr ""
 
-msgid "An error occurred while rendering the linter"
-msgstr ""
-
 msgid "An error occurred while reordering issues."
 msgstr ""
 
diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb
index 22f052e39b737e08c2e057f6fe7d0d6d906d81d5..24048aea8388cc8eec29e7ad3028e2ef748e2456 100644
--- a/spec/controllers/projects/ci/lints_controller_spec.rb
+++ b/spec/controllers/projects/ci/lints_controller_spec.rb
@@ -47,9 +47,9 @@
   describe 'POST #create' do
     subject { post :create, params: params }
 
-    let(:format) { :html }
-    let(:params) { { namespace_id: project.namespace, project_id: project, content: content, format: format } }
+    let(:params) { { namespace_id: project.namespace, project_id: project, content: content, format: :json } }
     let(:remote_file_path) { 'https://gitlab.com/gitlab-org/gitlab-foss/blob/1234/.gitlab-ci-1.yml' }
+    let(:parsed_body) { Gitlab::Json.parse(response.body) }
 
     let(:remote_file_content) do
       <<~HEREDOC
@@ -72,17 +72,23 @@
       HEREDOC
     end
 
-    shared_examples 'successful request with format json' do
-      context 'with format json' do
-        let(:format) { :json }
-        let(:parsed_body) { Gitlab::Json.parse(response.body) }
+    shared_examples 'returns a successful validation' do
+      before do
+        subject
+      end
 
-        it 'renders json' do
-          expect(response).to have_gitlab_http_status :ok
-          expect(response.content_type).to eq 'application/json'
-          expect(parsed_body).to include('errors', 'warnings', 'jobs', 'valid')
-          expect(parsed_body).to match_schema('entities/lint_result_entity')
-        end
+      it 'returns successfully' do
+        expect(response).to have_gitlab_http_status :ok
+      end
+
+      it 'renders json' do
+        expect(response.content_type).to eq 'application/json'
+        expect(parsed_body).to include('errors', 'warnings', 'jobs', 'valid')
+        expect(parsed_body).to match_schema('entities/lint_result_entity')
+      end
+
+      it 'retrieves project' do
+        expect(assigns(:project)).to eq(project)
       end
     end
 
@@ -92,25 +98,7 @@
         project.add_developer(user)
       end
 
-      shared_examples 'returns a successful validation' do
-        before do
-          subject
-        end
-
-        it 'returns successfully' do
-          expect(response).to have_gitlab_http_status :ok
-        end
-
-        it 'renders show page' do
-          expect(response).to render_template :show
-        end
-
-        it 'retrieves project' do
-          expect(assigns(:project)).to eq(project)
-        end
-
-        it_behaves_like 'successful request with format json'
-      end
+      it_behaves_like 'returns a successful validation'
 
       context 'using legacy validation (YamlProcessor)' do
         it_behaves_like 'returns a successful validation'
@@ -166,27 +154,23 @@
         subject
       end
 
+      it_behaves_like 'returns a successful validation'
+
       it 'assigns result with errors' do
-        expect(assigns[:result].errors).to match_array([
+        expect(parsed_body['errors']).to match_array([
           'jobs rubocop config should implement a script: or a trigger: keyword',
           'jobs config should contain at least one visible job'
         ])
       end
 
-      it 'render show page' do
-        expect(response).to render_template :show
-      end
-
-      it_behaves_like 'successful request with format json'
-
       context 'with dry_run mode' do
         subject { post :create, params: params.merge(dry_run: 'true') }
 
         it 'assigns result with errors' do
-          expect(assigns[:result].errors).to eq(['jobs rubocop config should implement a script: or a trigger: keyword'])
+          expect(parsed_body['errors']).to eq(['jobs rubocop config should implement a script: or a trigger: keyword'])
         end
 
-        it_behaves_like 'successful request with format json'
+        it_behaves_like 'returns a successful validation'
       end
     end
 
@@ -200,14 +184,6 @@
       it 'responds with 404' do
         expect(response).to have_gitlab_http_status(:not_found)
       end
-
-      context 'with format json' do
-        let(:format) { :json }
-
-        it 'responds with 404' do
-          expect(response).to have_gitlab_http_status :not_found
-        end
-      end
     end
   end
 end
diff --git a/spec/features/projects/ci/lint_spec.rb b/spec/features/projects/ci/lint_spec.rb
index eb2efb4357dd8d56a128854035cb8f8d641a3c2f..466c7ba215e08477257ff607400c1d8280621782 100644
--- a/spec/features/projects/ci/lint_spec.rb
+++ b/spec/features/projects/ci/lint_spec.rb
@@ -11,7 +11,6 @@
   let(:content_selector) { '.content .view-lines' }
 
   before do
-    stub_feature_flags(ci_lint_vue: false)
     project.add_developer(user)
     sign_in(user)
 
@@ -26,7 +25,6 @@
   describe 'YAML parsing' do
     shared_examples 'validates the YAML' do
       before do
-        stub_feature_flags(ci_lint_vue: false)
         click_on 'Validate'
       end
 
@@ -68,14 +66,6 @@
 
       it_behaves_like 'validates the YAML'
     end
-
-    describe 'YAML revalidate' do
-      let(:yaml_content) { 'my yaml content' }
-
-      it 'loads previous YAML content after validation' do
-        expect(page).to have_field('content', with: 'my yaml content', visible: false, type: 'textarea')
-      end
-    end
   end
 
   describe 'YAML clearing' do
@@ -89,7 +79,7 @@
       end
 
       it 'YAML content is cleared' do
-        expect(page).to have_field('content', with: '', visible: false, type: 'textarea')
+        expect(page).to have_field(class: 'inputarea', with: '', visible: false, type: 'textarea')
       end
     end
   end
diff --git a/spec/views/projects/ci/lints/show.html.haml_spec.rb b/spec/views/projects/ci/lints/show.html.haml_spec.rb
deleted file mode 100644
index f59ad3f5f845a306915b8971e8c293e2ae224326..0000000000000000000000000000000000000000
--- a/spec/views/projects/ci/lints/show.html.haml_spec.rb
+++ /dev/null
@@ -1,127 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'projects/ci/lints/show' do
-  include Devise::Test::ControllerHelpers
-  let_it_be(:user) { create(:user) }
-  let_it_be(:project) { create(:project, :repository) }
-  let(:lint) { Gitlab::Ci::Lint.new(project: project, current_user: user) }
-  let(:result) { lint.validate(YAML.dump(content)) }
-
-  describe 'XSS protection' do
-    before do
-      assign(:project, project)
-      assign(:result, result)
-      stub_feature_flags(ci_lint_vue: false)
-    end
-
-    context 'when builds attrbiutes contain HTML nodes' do
-      let(:content) do
-        {
-          rspec: {
-            script: '<h1>rspec</h1>',
-            stage: 'test'
-          }
-        }
-      end
-
-      it 'does not render HTML elements' do
-        render
-
-        expect(rendered).not_to have_css('h1', text: 'rspec')
-      end
-    end
-
-    context 'when builds attributes do not contain HTML nodes' do
-      let(:content) do
-        {
-          rspec: {
-            script: 'rspec',
-            stage: 'test'
-          }
-        }
-      end
-
-      it 'shows configuration in the table' do
-        render
-
-        expect(rendered).to have_css('td pre', text: 'rspec')
-      end
-    end
-  end
-
-  context 'when the content is valid' do
-    let(:content) do
-      {
-        build_template: {
-          script: './build.sh',
-          tags: ['dotnet'],
-          only: ['test@dude/repo'],
-          except: ['deploy'],
-          environment: 'testing'
-        }
-      }
-    end
-
-    before do
-      assign(:project, project)
-      assign(:result, result)
-      stub_feature_flags(ci_lint_vue: false)
-    end
-
-    it 'shows the correct values' do
-      render
-
-      expect(rendered).to have_content('Status: syntax is correct')
-      expect(rendered).to have_content('Tag list: dotnet')
-      expect(rendered).to have_content('Only policy: refs, test@dude/repo')
-      expect(rendered).to have_content('Except policy: refs, deploy')
-      expect(rendered).to have_content('Environment: testing')
-      expect(rendered).to have_content('When: on_success')
-    end
-
-    context 'when content has warnings' do
-      before do
-        allow(result).to receive(:warnings).and_return(['Warning 1', 'Warning 2'])
-      end
-
-      it 'shows warning messages' do
-        render
-
-        expect(rendered).to have_content('2 warning(s) found:')
-        expect(rendered).to have_content('Warning 1')
-        expect(rendered).to have_content('Warning 2')
-      end
-    end
-  end
-
-  context 'when the content is invalid' do
-    let(:content) { double(:content) }
-
-    before do
-      allow(result).to receive(:warnings).and_return(['Warning 1', 'Warning 2'])
-      allow(result).to receive(:errors).and_return(['Undefined error'])
-
-      assign(:project, project)
-      assign(:result, result)
-      stub_feature_flags(ci_lint_vue: false)
-    end
-
-    it 'shows error message' do
-      render
-
-      expect(rendered).to have_content('Status: syntax is incorrect')
-      expect(rendered).to have_content('Undefined error')
-      expect(rendered).not_to have_content('Tag list:')
-    end
-
-    it 'shows warning messages' do
-      render
-
-      expect(rendered).to have_content('2 warning(s) found:')
-      expect(rendered).to have_content('Warning 1')
-      expect(rendered).to have_content('Warning 2')
-    end
-  end
-end